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
在与模板声明对应的行上。到底是怎么回事?我一直使用这种语法来启用和禁用我的模板 类 并且它总是在实例化行而不是在声明行抛出错误..
你能不能迂腐地解释一下我这里做错了什么?
N
不是依赖的非类型模板参数; [temp.dep.temp]/p2
A non-type template-argument is dependent if its type is dependent or the constant expression it specifies is value-dependent.
因此,错误不是发生替换失败,而是直接从格式错误的代码中发出。
来自 http://en.cppreference.com/w/cpp/types/enable_if:(强调我的)
This metafunction is a convenient way to leverage SFINAE to conditionally remove functions from overload resolution based on type traits and to provide separate function overloads and specializations for different type traits. std::enable_if
can be used as an additional function argument (not applicable to operator overloads), as a return type (not applicable to constructors and destructors), or as a class template or function template parameter.
您不能使用它来启用或禁用 [=12=] 或 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
关于为什么错误发生在模板定义而不是实例化,其他答案是正确的。
I need an error to be thrown when trying to instantiate something like `more_than_99 <0> x;' on the line where I try to instantiate it. Something like "hey, this type doesn't exist".
这样的怎么样?
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>
的恶意实例化。
如果您有 class 专业化(或函数重载),enable_if
是有意义的。它用于根据模板参数在一种实现和另一种实现之间选择,如果不满足条件则不会触发错误。
想法是"enable this specialization if the condition is met, otherwise fall back to the non-specialized version"。
在你的情况下,你可能想要这样的东西:
#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
}
使用静态断言:
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;
我显然没有足够的 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
在与模板声明对应的行上。到底是怎么回事?我一直使用这种语法来启用和禁用我的模板 类 并且它总是在实例化行而不是在声明行抛出错误..
你能不能迂腐地解释一下我这里做错了什么?
N
不是依赖的非类型模板参数; [temp.dep.temp]/p2
A non-type template-argument is dependent if its type is dependent or the constant expression it specifies is value-dependent.
因此,错误不是发生替换失败,而是直接从格式错误的代码中发出。
来自 http://en.cppreference.com/w/cpp/types/enable_if:(强调我的)
This metafunction is a convenient way to leverage SFINAE to conditionally remove functions from overload resolution based on type traits and to provide separate function overloads and specializations for different type traits.
std::enable_if
can be used as an additional function argument (not applicable to operator overloads), as a return type (not applicable to constructors and destructors), or as a class template or function template parameter.
您不能使用它来启用或禁用 [=12=] 或 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
关于为什么错误发生在模板定义而不是实例化,其他答案是正确的。
I need an error to be thrown when trying to instantiate something like `more_than_99 <0> x;' on the line where I try to instantiate it. Something like "hey, this type doesn't exist".
这样的怎么样?
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>
的恶意实例化。
enable_if
是有意义的。它用于根据模板参数在一种实现和另一种实现之间选择,如果不满足条件则不会触发错误。
想法是"enable this specialization if the condition is met, otherwise fall back to the non-specialized version"。
在你的情况下,你可能想要这样的东西:
#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
}
使用静态断言:
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;