问题
I am trying to get the value of a template parameter of a user-defined class deduced (http://wg21.link/p0732r2), using GCC 9.1 with -std=c++2a.
struct user_type {
int a;
constexpr user_type( int a ): a( a ){}
};
template< user_type u > struct value {};
template< user_type u > void f( value< u > arg ){}
void g(){
f( value< user_type( 0 ) >() ); // error here
}
compiler explorer: https://godbolt.org/z/6v_p_R
I get the error:
source>:8:30: note: template argument deduction/substitution failed:
<source>:11:33: note: couldn't deduce template parameter 'u'
11 | f( value< user_type( 0 ) >() );
Am I doing something wrong? I had expected such a value to be deductible.
As suggested by Nikita I added == and != operators to user-type, but that made no difference.
struct user_type {
int a;
constexpr user_type( int a ): a( a ){}
constexpr bool operator==( const user_type & arg ) const {
return a == arg.a;
}
constexpr bool operator!=( const user_type & arg ) const {
return a != arg.a;
}
};
回答1:
This should be ill-formed:
struct user_type {
int a;
constexpr user_type( int a ): a( a ){}
};
template< user_type u > struct value {};
In order to be a template non-type parameter, you need to satisfy [temp.param]/4:
A non-type template-parameter shall have one of the following (optionally cv-qualified) types:
- a literal type that has strong structural equality ([class.compare.default]),
- [...]
Where strong structural equality requires, from [class.compare.default]/3:
A type C has strong structural equality if, given a glvalue x of type const C, either:
- C is a non-class type and [...], or
- C is a class type with an == operator defined as defaulted in the definition of C, x == x is well-formed when contextually converted to bool, all of C's base class subobjects and non-static data members have strong structural equality, and C has no mutable or volatile subobjects.
The key is that we need a defaulted ==
in the type... and we don't have one, so our type doesn't have strong structural equality, so it cannot be used as a template non-type parameter.
However, gcc doesn't let you declare such an operator yet, so you can't fix the problem.
This is just an incomplete implementation of a new feature.
来源:https://stackoverflow.com/questions/55991986/deducing-a-user-defined-value-template-argument-c2a-p0732r2