不能使用Enable_if来禁用此声明
enable_if cannot be used to disable this declaration
我显然没有足够的SFINAE经验来处理这个问题。实际上,直到现在我的印象是它还可以工作,这种问题在过去的半个小时里开始出现,在我的代码中到处都是。
#include <iostream>
using namespace std;
template <unsigned int N, typename = typename enable_if <N >= 100> :: type>
struct more_than_99
{
};
int main()
{
more_than_99 <0> c;
}
说No type named 'type' in 'std::__1::enable_if<false, void>'; 'enable_if' cannot be used to disable this declaration
放在模板声明对应的行中。发生了什么事?我一直使用这种语法来启用和禁用我的模板类,它总是在实例化行抛出错误,而不是在声明行。
你能解释一下我哪里做错了吗?
关于为什么错误发生在模板定义而不是实例化时,其他答案是正确的。
我需要在尝试实例化的行上抛出一个错误,例如' more_than_99 <0> x;'。比如"嘿,这个类型不存在"
这样的怎么样?
template <unsigned int N, bool B = (N>=100)>
struct more_than_99;
template <unsigned int N>
struct more_than_99<N,true>
{};
int main()
{
more_than_99 <0> c; // error: implicit instantiation of undefined template 'more_than_99<0, false>'
}
为了使它更健壮,并试图防止意外实例化more_than_99<0,true>
,这也适用于(c++ 11):
template <unsigned int N, bool B>
struct _impl_more_than_99;
template <unsigned int N>
struct _impl_more_than_99<N,true>
{};
template <unsigned int N>
using more_than_99 = _impl_more_than_99<N, (N>=100)>;
int main()
{
more_than_99 <0> c; // error: implicit instantiation of undefined template '_impl_more_than_99<0, false>'
}
虽然错误消息引用了_impl_
类型。
您可以将_impl_
隐藏在一个详细的名称空间或其他地方,并且只记录more_than_99
别名,就好像它是实际类型一样。
但是,您将无法阻止_impl_more_than_99<0,true>
的恶意实例化。
N
不是一个依赖的非类型模板参数;[temp.dep.temp]/p2
如果非类型模板参数的类型是依赖的,或者它指定的常量表达式是值依赖的,则该参数是依赖的。
因此,不会发生替换失败,而是直接从格式错误的代码发出错误。
enable_if
是有意义的,如果你有一个类专门化(或函数重载)。它用于根据模板参数在一种实现和另一种实现之间选择,如果不满足条件则不会触发错误。
其思想是"如果满足条件则启用此专门化,否则退回到非专门化版本"。
在您的情况下,您可能需要这样的内容:
#include <iostream>
#include <type_traits>
using namespace std;
template<unsigned int N, typename = void >
struct more_than_99
{
// Implementation if N <= 99
enum { value = false };
};
template <unsigned int N>
struct more_than_99<N, typename enable_if <N >= 100> :: type>
{
// Implementation if N >= 100
enum { value = true };
};
int main()
{
cout << more_than_99 <0>::value << endl; //false
cout << more_than_99 <100>::value << endl; //true
}
From http://en.cppreference.com/w/cpp/types/enable_if:(强调我的)
这个元函数是一种方便的方法,可以利用SFINAE根据类型特征有条件地从重载解析中删除函数,并为不同的类型特征提供单独的函数重载和专门化。
std::enable_if
可以用作附加的函数实参(不适用于操作符重载)、返回类型(不适用于构造函数和析构函数),或者作为类模板或函数模板形参。
不能启用或禁用class
或struct
。
也许你正在寻找这样的东西:
namespace detail
{
struct more_than_99 {};
template <bool> Helper;
template <> Helper<true>
{
using type = more_than_99;
};
}
template <unsigned int N> struct selector
{
using type = typename detail::Helper<N >= 100>::type
};
using type = selector<10>::type; // Error.
using type = selector<100>::type; // OK.
// type == detail::more_than_99
使用static assert:
template<unsigned int N>
struct more_than_99
{
static_assert(N >= 100, "N must be more than 99");
};
more_than_99<1> m1;
会导致如下编译错误:
testM99.cpp:6:3: error: static_assert failed "N must be more than 99"
static_assert(N >= 100, "N must be more than 99");
^ ~~~~~~~~
testM99.cpp:12:19: note: in instantiation of template class 'more_than_99<1>'
requested here
more_than_99<1> m1;
- .cpp和.h文件中的模板专用化声明
- 未在作用域中声明unordered_map
- C++避免重复声明的语法是什么
- 如何确保C++函数在定义之前声明(如override关键字)
- 错误:未在此范围内声明'reverse'
- 奇怪的(对我来说)返回声明 - 在谷歌上找不到任何关于它的信息
- 为什么在定义函数之前先声明它
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- 如何将enable-if与模板参数和参数包一起使用
- #ifdef和未声明的标识符
- 没有显式声明的int[]中的foreach
- 在基于范围的for循环中使用结构化绑定声明
- 在将变量声明为引用时,堆在释放后使用
- C++:无法访问声明的受保护成员
- 为什么我不能在一个类的不同行中声明和定义成员变量?
- 我不明白为什么我声明一个空的内部结构并将其传递给构造函数
- 使用cmake从源代码构建MySQL连接器/C++失败(与以前的声明冲突)
- 在函数内部的声明中初始化数组,并在外部使用它
- Visual Studio中的函数声明和函数定义问题
- c++类声明时,相同的例程,不同的成员变量类型