I have template class C
that has a non-type but reference template parameter to a type P
:
class P {
public:
int x;
int y;
};
template <const P &x>
class C {
public:
const int &f() { return x.x; }
};
I declared a global variable of type P
:
P p = {33,44};
I also declared a function that returns a reference to p
:
constexpr const P &h() { return p; }
And then tried to use these in the following :
C<p> o; // line 1
C<h()> oo; // line 2
Of course I have no problem with the first instantiation but the second. My compiler complains:
error: non-type template argument does not refer to any declaration
Why is so ? I was unable to find an argument against it in the norm. I am not sure that it is exactly the same problem as in Calling constexpr in default template argument, where the discussion was about point of instantiation of nested instanciation. Here it is more a type problem, but which one ? My function h()
returns a reference to a well defined variable of the well defined type (const P &
). I expected that some inlining would take place a give the right result but it is not the case. Could you tell me why ?
Declaring the function as inline doesn't change anything to the problem.
Experiments were done with Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn
. I also tried with g++-mp-4.8 (MacPorts gcc48 4.8.3_2) 4.8.3
and the error was reported as:
'h()' is not a valid template argument for type 'const P&' because it is not an object with external linkage
It looks like my call to h()
(which is a constexpr
so compile-time computable) is not seen as such...
I forgot to say that the problem is the same if we try with another reference like this:
const P &pp = p;
and then
C<pp> oo;
this time the first compiler says:
non-type template argument of reference type 'const P &' is not an object
and the second:
error: could not convert template argument 'pp' to 'const P &'
pp
is not an object? pp
is not of type const P&
? Well I can use it as is it one... I know it is a reference but indistinguishable from a native reference, or ?