Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can an lvalue reference non-type template parameter be inferred?

I have the following code, which I cannot get to work:

struct foo {};
foo foo1 = {};

template <foo& F>
class FooClass {};

template <foo& F>
void foobar(FooClass<F> arg) {
}

int main() {
    FooClass<foo1> f;
    foobar(f);
}

The error is:

main.cpp:14:5: error: no matching function for call to 'foobar'

note: candidate template ignored: substitution failure : deduced non-type template argument does not have the same type as the its corresponding template parameter ('foo' vs 'foo &')

Is it at all possible to infer lvalue reference template parameters? If so, how should it be done?

like image 887
molf Avatar asked Feb 01 '16 20:02

molf


People also ask

Which parameter is allowed for non-type template?

Which parameter is legal for non-type template? Explanation: The following are legal for non-type template parameters:integral or enumeration type, Pointer to object or pointer to function, Reference to object or reference to function, Pointer to member.

What is a template parameter?

In UML models, template parameters are formal parameters that once bound to actual values, called template arguments, make templates usable model elements. You can use template parameters to create general definitions of particular types of template.


1 Answers

This is precisely covered by CWG 2091:

According to 14.8.2.5 [temp.deduct.type] paragraph 17,

If P has a form that contains <i>, and if the type of the corresponding value of A differs from the type of i, deduction fails.

This gives the wrong result for an example like:

template<int &> struct X;
template<int &N> void f(X<N>&);
int n;
void g(X<n> &x) { f(x); }

Here, P is X<N>, which contains <i>. The type of i is int&. The corresponding value from A is n, which is a glvalue of type int. Presumably this should be valid.

I think this rule means to say something like,

If P has a form that contains <i>, and the type of i differs from the type of the corresponding template parameter of the template named by the enclosing simple-template-id, deduction fails.

As noted by @dyp, [temp.deduct.type]/17 should be more permissive. In your example, the argument in FooClass<F> (F) does not have reference type - it's an lvalue of type foo. The template parameter of FooClass is a reference. The DR was resolved last year.

like image 87
Columbo Avatar answered Nov 15 '22 18:11

Columbo