【发布时间】:2014-05-20 10:56:21
【问题描述】:
考虑以下代码,它尝试使用 SFINAE 根据模板参数提供不同的方法实现。
#include <type_traits>
#include <iostream>
template<bool S>
struct C{
template<typename std::enable_if<!S>::type* = nullptr>
int foo(int i){
return i + 1;
}
template<typename std::enable_if<S>::type* = nullptr>
int foo(int i){
return i;
}
};
int main(){
C<true> c1;
C<false> c2;
std::cout << c1.foo(0) << c2.foo(0) << std::endl;
}
这个例子的灵感来自std::enable_if的参考页面。如您所见,struct C<S> 有两个 foo 方法。如果S 是true,则应启用一个,如果S 是false,则应启用另一个。但是,代码无法编译,但会引发以下错误:
src/test.cpp: In instantiation of ‘struct C<true>’:
src/test.cpp:19:12: required from here
src/test.cpp:7:8: error: no type named ‘type’ in ‘struct std::enable_if<false, void>’
int foo(int i){
^
src/test.cpp: In instantiation of ‘struct C<false>’:
src/test.cpp:20:13: required from here
src/test.cpp:12:8: error: no type named ‘type’ in ‘struct std::enable_if<false, void>’
int foo(int i){
因此,编译器似乎完全忽略了 SFINAE 并在发现未启用类型时引发错误。我在这里做错了什么?
【问题讨论】:
-
@ecatmur:这不是重复的。另一个问题显然没有使用模板方法,这是其错误的根源。我的方法是模板方法,因此其他问题的答案不适用于这个问题。仅仅因为问题标题听起来相似而简单地重复关闭问题是非常侮辱的。强大的(适度)权力带来了巨大的责任,即,请在关闭问题之前彻底阅读问题。
-
(我之前对这个评论的措辞是错误的。)
std::enable_if<S>::type不依赖于任何方法的模板参数,因为S是类的模板参数,而不是方法。 -
@hvd:那么,这些方法是什么?毕竟,他们在定义之上有一个模板指令。
-
你说得对,它是一种模板方法,当我注意到我的措辞完全错误时,我编辑了我之前的评论(在你回复之前)。
标签: c++ templates sfinae typetraits