variable template within class produces non-static data member cannot be constexpr

The following code:

//{=======================================
#include <type_traits>
struct variable_template
{
    template <int Value>
    std::integral_constant<int,Value> constexpr
  value{}
    ;
};
#include <iostream>
#include <iomanip>
int main()
{
    std::cout<<
      variable_template::
      value<1>()<<std::endl;
    return 0;
}
//}=======================================
produces error:
//{=======================================
/home/evansl/dwnlds/llvm/3.5/binary/clang+llvm-3.5.0-x86_64-linux-gnu/bin/clang++
-c -O0 -g -stdlib=libc++ -std=c++14 -ftemplate-backtrace-limit=0
-I/home/evansl/prog_dev/clang/libcxx
-I/home/evansl/prog_dev/boost/sandbox/rw/non_variadic_templates
-I/home/evansl/prog_dev/boost/sandbox/rw/sandbox/lje
-I/home/evansl/prog_dev/boost/boost-releases/ro/boost_1_56_0
-DTYPE_AT_IMPL=0 -ftemplate-depth=324 variable_templates.cpp -MMD -o
/tmp/build/clangxx3_5_bin/clang/libcxx/variable_templates.o
variable_templates.cpp:23:39: error: non-static data member cannot be
constexpr; did you intend to make it static?
    std::integral_constant<int,Value> constexpr
                                      ^
                                      static
1 error generated.
//}=======================================
when compiled with the binary clang downloaded from:

http://llvm.org/releases/3.5.0/clang+llvm-3.5.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz

and used on system:

Linux lje-OptiPlex-9020 3.13.0-39-generic #66-Ubuntu SMP Tue Oct 28
13:30:27 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

The code is, AFAICT, essentially the same as the `struct
matrix_measures' in section 3.2 of:

  http://isocpp.org/files/papers/N3651.pdf

Is this a clang bug or is the code somehow wrong?

TIA.

-regards,
Larry

My guess is that the proposal was written assuming a certain implementation of constexpr that never panned out.

It looks like both GCC and Clang expect constexpr member variables to be explicitly marked static:

const.cpp:5:19: error: non-static data member 'f' declared 'constexpr'
   constexpr foo f{};
                   ^

(is GCC 4.9's diagnostic - for a simple non-template constexpr member variable)

My guess is that the proposal was written assuming a certain implementation
of constexpr that never panned out.

It looks like both GCC and Clang expect constexpr member variables to be
explicitly marked static:

const.cpp:5:19: error: non-static data member 'f' declared 'constexpr'
   constexpr foo f{};
                   ^

(is GCC 4.9's diagnostic - for a simple non-template constexpr member variable)

That's sad because, as n3651 says on pp. 2-3:

  The main problems with “static data member” are:

  • they require “duplicate” declarations: once inside the class
    template, once outside the class template to provide the “real”
    definition in case the constants is odr-used.

  • programmers are both miffed and confused by the necessity of
    providing twice the same declaration. By contrast, “ordinary”
    constant declarations do not need duplicate declarations.

Also, the clang status page:

  Clang - C++ Programming Language Status

reference n3651 below the section title:

  C++14 implementation status

Hence, I thought that's what clang implemented.

In addition, the latest standard *draft*:

  https://isocpp.org/files/papers/N3797.pdf

contains the n3651 matrix_constants example on p. 313.

Is there some more current standards document which requires the
static qualifier on variable templates within a class?

TIA.

-regards,
Larry

> My guess is that the proposal was written assuming a certain
implementation
> of constexpr that never panned out.
>
> It looks like both GCC and Clang expect constexpr member variables to be
> explicitly marked static:
>
> const.cpp:5:19: error: non-static data member 'f' declared 'constexpr'
> constexpr foo f{};
> ^
>
> (is GCC 4.9's diagnostic - for a simple non-template constexpr member
variable)
>
That's sad because, as n3651 says on pp. 2-3:

  The main problems with “static data member” are:

  • they require “duplicate” declarations: once inside the class
    template, once outside the class template to provide the “real”
    definition in case the constants is odr-used.

  • programmers are both miffed and confused by the necessity of
    providing twice the same declaration. By contrast, “ordinary”
    constant declarations do not need duplicate declarations.

I don't think this is referring to the need to write "static" in a static
member variable template declaration.

This is referring to the workaround (In the absence of static variables) of
using a class template with a nested static data member - pointing out that
when you write it that way (see the example near this workaround
description) you have to write the class, the variable declaration, and the
variable definition. Whereas with a plain non-member variable template you
don't need separate declaration/definition - the variable template (like a
function template) is the declaration+definition all in one.

Also, the clang status page:

  Clang - C++ Programming Language Status

reference n3651 below the section title:

  C++14 implementation status

Hence, I thought that's what clang implemented.

Ah, here's the wording that's important:

"A variable template at class scope is a static data member template." in
14 paragraph 1.

(sorry, I'd been looking in the static member parts of the spec, not the
variable template parts, which have this special case)

It looks like this just hasn't been implemented - Larisse (CC'd) did the
initial variable template implementation. Perhaps she can tell us if that
was a more recent change, whether it's planned to be fixed, or a bug in the
spec etc.

I don’t understand the comment; but, I can tell that a class member variable template must be declared static. 'constexpr’ness is immaterial to that.

– Gaby

> My guess is that the proposal was written assuming a certain
implementation
> of constexpr that never panned out.
>
> It looks like both GCC and Clang expect constexpr member variables to be
> explicitly marked static:
>
> const.cpp:5:19: error: non-static data member 'f' declared 'constexpr'
> constexpr foo f{};
> ^
>
> (is GCC 4.9's diagnostic - for a simple non-template constexpr member
variable)
>
That's sad because, as n3651 says on pp. 2-3:

  The main problems with “static data member” are:

  • they require “duplicate” declarations: once inside the class
    template, once outside the class template to provide the “real”
    definition in case the constants is odr-used.

then don't put it in a class.

But then I don't understand why the problem was mentioned in n3651 on
pp. 2-3. I thought one of the reasons for the proposal was to free
programmers from the need for "duplicate" declarations; however, the
solution:

  don't put it in a class

seems to indicate that the problem can be avoided simply by not
creating the problem. IOW, the "duplicate" declaration in the
archetypical example on p. 2, the numeric_limits example, can be
avoided by not putting it in a template class (or struct in this
case).

In that case, I don't understand the rationale for proposal.

I must be missing something :frowning:

-regards,
Larry

[snip]

If you hate (as I do) having to put a variable in a class template just so
that you can abstract over its type but then you are forced to provide a
"duplicate" declaration (the real definition) outside the class, then
variable templates remove that pain: they do what they were designed for.

If you want to change the language rules for not having to "redeclare" a
static data member at namespace scope, then that is a *different problem*;
one you should write a proposal for if you feel strongly about it.

-- Gaby

My guess is that the proposal was written assuming a certain

implementation

of constexpr that never panned out.

It looks like both GCC and Clang expect constexpr member variables to

be

explicitly marked static:

const.cpp:5:19: error: non-static data member 'f' declared 'constexpr'
   constexpr foo f{};
                   ^

(is GCC 4.9's diagnostic - for a simple non-template constexpr member

variable)

That's sad because, as n3651 says on pp. 2-3:

  The main problems with “static data member” are:

  • they require “duplicate” declarations: once inside the class
    template, once outside the class template to provide the “real”
    definition in case the constants is odr-used.

then don't put it in a class.

But then I don't understand why the problem was mentioned in n3651 on
pp. 2-3. I thought one of the reasons for the proposal was to free
programmers from the need for "duplicate" declarations; however, the
solution:

  don't put it in a class

seems to indicate that the problem can be avoided simply by not
creating the problem. IOW, the "duplicate" declaration in the
archetypical example on p. 2, the numeric_limits example, can be
avoided by not putting it in a template class (or struct in this
case).

In that case, I don't understand the rationale for proposal.

I must be missing something :frowning:

-regards,
Larry

If you hate (as I do) having to put a variable in a class template just so
that you can abstract over its type but then you are forced to provide a
"duplicate" declaration (the real definition) outside the class, then
variable templates remove that pain: they do what they were designed for.

That's what I was hoping.

Maybe the problem is I'm not making my point clear enough.
If I understand your proposal, then the following code should
compile without error when:
  !defined(USE_STATIC) && !defined(DUPLICATE_DECLARATION)
yet, with clang 3.5, it only compiles with both these
macros are define.

Is clang wrong?

variable_templates.cpp (1.18 KB)

>
>>>
>>>>> My guess is that the proposal was written assuming a certain
>>>> implementation
>>>>> of constexpr that never panned out.
>>>>>
>>>>> It looks like both GCC and Clang expect constexpr member variables to
>> be
>>>>> explicitly marked static:
>>>>>
>>>>> const.cpp:5:19: error: non-static data member 'f' declared
'constexpr'
>>>>> constexpr foo f{};
>>>>> ^
>>>>>
>>>>> (is GCC 4.9's diagnostic - for a simple non-template constexpr member
>>>> variable)
>>>>>
>>>> That's sad because, as n3651 says on pp. 2-3:
>>>>
>>>> The main problems with “static data member” are:
>>>>
>>>> • they require “duplicate” declarations: once inside the class
>>>> template, once outside the class template to provide the “real”
>>>> definition in case the constants is odr-used.
>>>>
>>>
>>> then don't put it in a class.
>>>
>>
>> But then I don't understand why the problem was mentioned in n3651 on
>> pp. 2-3. I thought one of the reasons for the proposal was to free
>> programmers from the need for "duplicate" declarations; however, the
>> solution:
>>
>> don't put it in a class
>>
>> seems to indicate that the problem can be avoided simply by not
>> creating the problem. IOW, the "duplicate" declaration in the
>> archetypical example on p. 2, the numeric_limits example, can be
>> avoided by not putting it in a template class (or struct in this
>> case).
>>
>> In that case, I don't understand the rationale for proposal.
>>
>> I must be missing something :frowning:
>>
>> -regards,
>> Larry
>>
>
> If you hate (as I do) having to put a variable in a class template just
so
> that you can abstract over its type but then you are forced to provide a
> "duplicate" declaration (the real definition) outside the class, then
> variable templates remove that pain: they do what they were designed for.

That's what I was hoping.

Maybe the problem is I'm not making my point clear enough.
If I understand your proposal, then the following code should
compile without error when:
  !defined(USE_STATIC) && !defined(DUPLICATE_DECLARATION)
yet, with clang 3.5, it only compiles with both these
macros are define.

Is clang wrong?

You still have variable template as class member in your original example,
so you have to obey the rules of class members...

Note that your original example was (also) missing the keyword "static" --
the C++ object model does not permit non-static data member templates.

-- Gaby

On 11/15/2014 04:12 PM, Gabriel Dos Reis wrote:> On Sat, Nov 15, 2014 at
9:13 AM, Larry Evans <cppljevans@suddenlink.net>

wrote:

[snip]

If you hate (as I do) having to put a variable in a class template
just so that you can abstract over its type but then you are
forced to provide a "duplicate" declaration (the real definition)
outside the class, then variable templates remove that pain: they
do what they were designed for.

That's what I was hoping.

Maybe the problem is I'm not making my point clear enough.
If I understand your proposal, then the following code should
compile without error when:
  !defined(USE_STATIC) && !defined(DUPLICATE_DECLARATION)
yet, with clang 3.5, it only compiles with both these
macros are define.

Is clang wrong?

You still have variable template as class member in your original example,
so you have to obey the rules of class members...

Note that your original example was (also) missing the keyword "static" --
the C++ object model does not permit non-static data member
templates.

But the matrix_constants example on p. 4 of n3651 also is
missing the keyword "static". The paragraph above that
example says:

  A variable template at class scope is a static data member
  template.

So I'm guessing that the compiler should interpret sigma1 as
a class *static* member instead of instance member,
*despite* there being no "static" keyword *in the example*
(IOW, the sigma1 belongs to the class, not the instances of
that class. IOW if:

  matrix_constants mc1, mc2;

there would be only one instance of matrix_constants::sigma1
shared by mc1 and mc2. IOW, there would be no mc1.sigma1 or
mc2.sigma1, there would only be matrix_constants::sigma1.)
Is that right?

Now clang3.5 *requires* the static keyword despite it being
absent in the n3651 example. However, *with* static,
clang3.5 also requires the "undesired" duplicate declaration
to avoid a link-time error about "missing" sigma1
definition. Hence, clang3.5 is wrong in its implementation
of n3651, AFAICT. Right?

-- Larry

On 11/14/2014 01:01 PM, David Blaikie wrote:> On Fri, Nov 14, 2014 at
4:23 AM, Larry Evans <cppljevans@suddenlink.net>

wrote:

My guess is that the proposal was written assuming a certain

implementation

of constexpr that never panned out.

It looks like both GCC and Clang expect constexpr member variables to be
explicitly marked static:

const.cpp:5:19: error: non-static data member 'f' declared 'constexpr'
   constexpr foo f{};
                   ^

(is GCC 4.9's diagnostic - for a simple non-template constexpr member

variable)

That's sad because, as n3651 says on pp. 2-3:

  The main problems with “static data member” are:

  • they require “duplicate” declarations: once inside the class
    template, once outside the class template to provide the “real”
    definition in case the constants is odr-used.

  • programmers are both miffed and confused by the necessity of
    providing twice the same declaration. By contrast, “ordinary”
    constant declarations do not need duplicate declarations.

I don't think this is referring to the need to write "static" in a static
member variable template declaration.

This is referring to the workaround (In the absence of static

variables) of

using a class template with a nested static data member - pointing out

that

when you write it that way (see the example near this workaround
description) you have to write the class, the variable declaration,

and the

variable definition. Whereas with a plain non-member variable template you
don't need separate declaration/definition - the variable template (like a
function template) is the declaration+definition all in one.

So, if the keyword, static, *is* used, a separate definition *outside* of
the class (IOW, in, I think the terminology is, "in namespace scope")
is needed. In contrast, if keyword static *is not* used, the
separate definition is not required ( even though the
variable is still a static member) ?

Also, the clang status page:

  Clang - C++ Programming Language Status

reference n3651 below the section title:

  C++14 implementation status

Hence, I thought that's what clang implemented.

Ah, here's the wording that's important:

"A variable template at class scope is a static data member template." in
14 paragraph 1.

(sorry, I'd been looking in the static member parts of the spec, not the
variable template parts, which have this special case)

It looks like this just hasn't been implemented - Larisse (CC'd) did the
initial variable template implementation. Perhaps she can tell us if that
was a more recent change, whether it's planned to be fixed, or a bug

in the

spec etc.

The reponse to my comment here:

  Talk:cpp/language/variable template - cppreference.com

says:

  the examples in the standard have an error, mentioned
  _here_

where _here_ links to:

which is, essentially, the question posed in my OP to this
thread. In addition, the comments to that SO post contain:

  _The committee is aware that the wording for variable
  templates needs some help in various places_

which links to:

https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/ZTw3W3vjWWs

which I'm still trying to digest :(, but it seems to
indicate the variable template meaning is ambiguous; hence,
one can't say clang has a bug in its implementation
of variable templates.

-regards,
Larry
[snip]

My last response to the talk:

http://en.cppreference.com/w/Talk:cpp/language/variable_template

contains:

  the definition outside the class definition is ...
  *only* optional if a reference is not made to the template variable.

and a reference to the standard's 9.4.2p3 is made to justify that
conclusion.

Hence, AFAICT, clang is correct in requiring the outside class defintion
when the template variable is referenced.

-regards,
Larry

Good.

– Gaby