Deducing a user-defined-value template argument (C++2a, P0732R2)

百般思念 提交于 2019-12-30 05:08:28

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!