Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;(14/17)将枚举用作非类型模板参数时出现奇怪的无底模板递归错误_C++_C++14_C++17_Enumeration_Template Specialization - Fatal编程技术网

C++ C++;(14/17)将枚举用作非类型模板参数时出现奇怪的无底模板递归错误

C++ C++;(14/17)将枚举用作非类型模板参数时出现奇怪的无底模板递归错误,c++,c++14,c++17,enumeration,template-specialization,C++,C++14,C++17,Enumeration,Template Specialization,以下代码: #include <iostream> #include <type_traits> enum EnumT{Invalid = 0, Float, N_Types};//enum triggers the problem; works fine with ints template<typename T, EnumT id_> struct X { template<EnumT id = id_, std::en

以下代码:

#include <iostream>
#include <type_traits>

enum EnumT{Invalid = 0, Float, N_Types};//enum triggers the problem; works fine with ints

template<typename T, EnumT id_>
struct X
{
  template<EnumT id = id_,
           std::enable_if_t<(id != Float)> * = nullptr>
  constexpr explicit X(T v): val_(v)
  {
    std::cout<<"cnstr..."<<id<<"\n";
  }

  template<EnumT id = id_,
           std::enable_if_t<(id == Float)> * = nullptr>
  constexpr /*explicit*/ X(float v): val_(v)
  {
    std::cout<<"cnstr..."<<id<<"\n";
  }


  template<typename OUT,
           EnumT id = id_,
           std::enable_if_t<(id == Float)> * = nullptr>
  explicit operator OUT() const
  {
    std::cout<<"conv. op....\n";
    return static_cast<float>(val_);
  }
private:
  T val_;
};

using Y = X<float, Float>;

bool operator==(Y const &lhs, Y const &rhs){
    return static_cast<float>(lhs) == static_cast<float>(rhs);
}
#包括
#包括
枚举枚举{Invalid=0,Float,N_类型}//枚举触发了问题;可以很好地处理ints
模板
结构X
{
模板
constexpr显式X(tv):val_v(v)
{
标准::cout
|                                                ^~~~~~~
编译终止。
返回的编译器:1
但是,如果我用
int
或作用域枚举替换
EnumT
,则一切都可以正常编译。还要注意在第二个构造函数中注释掉的
explicit
关键字。如果我取消注释它,则使用
EnumT
的此版本也可以正常编译


任何人都可以解释到底发生了什么?提前谢谢。

你确定它可以用作用域枚举编译好吗?真的很奇怪。使用
操作符!=
,使用
操作符==
失败。学习者:是的。只需将
枚举枚举枚举
替换为
枚举类枚举
并将
浮点
替换为
枚举::F即可loat
(在
cout
中,用
static\u cast(id)
)替换
id
)并试一试。它对我来说编译得很好。而且……所有东西都可以编译得很好w/clang8.0.0.:因此,有两个问题,其中至少有一个似乎是编译器错误:(1)
=
EnumT
之间触发重载解析,其中
操作符==(consty&,consty&)
成为候选;(2)
操作符==(consty&,consty&)
触发
Y
构造函数的实例化;我最感兴趣的是为什么(2)会发生?这是预期的还是一个bug?
<source>: In substitution of 'template<EnumT id, std::enable_if_t<(id == Float), void>* <anonymous> > constexpr X<float, Float>::X(float) [with EnumT id = Float; std::enable_if_t<(id == Float), void>* <anonymous> = <missing>]':
<source>:17:48:   recursively required by substitution of 'template<EnumT id, std::enable_if_t<(id == Float), void>* <anonymous> > constexpr X<float, Float>::X(float) [with EnumT id = Float; std::enable_if_t<(id == Float), void>* <anonymous> = <missing>]'
<source>:17:48:   required by substitution of 'template<EnumT id, std::enable_if_t<(id == Float), void>* <anonymous> > constexpr X<float, Float>::X(float) [with EnumT id = Float; std::enable_if_t<(id == Float), void>* <anonymous> = <missing>]'
<source>:26:48:   required by substitution of 'template<class OUT, EnumT id, std::enable_if_t<(id == Float), void>* <anonymous> > X<float, Float>::operator OUT<OUT, id, <enumerator> >() const [with OUT = float; EnumT id = Float; std::enable_if_t<(id == Float), void>* <anonymous> = <missing>]'
<source>:39:34:   required from here
<source>:17:48: fatal error: template instantiation depth exceeds maximum of 900 (use '-ftemplate-depth=' to increase the maximum)
   17 |            std::enable_if_t<(id == Float)> * = nullptr>
      |                                                ^~~~~~~
compilation terminated.
Compiler returned: 1