该代码失败在大多数编译器来编译,但起初我直觉预期SFINAE保护我:SFINAE,演绎与实例
:
typedef void (*A)();
template < typename T >
struct a_metafun { typedef typename T::type type; };
template < typename T >
typename a_metafun<T>::type f(T) {}
template < typename T>
void f(T(*)()) {}
int main() { f(A()); }
我可以以至少两种方式解决这个问题1)改变的“metafun” F(定义),以:
template < typename T > typename T::type f(T) {}
2)界定“a_metafun”,使得它分析T和具有类型,如果T具有一个,并且不我f,将它不...但没有实例化错误两种方式:
BOOST_MPL_HAS_XXX_TRAIT_DEF(type)
typedef < template T, bool = has_type<T>::value >
struct a_metafun { };
typedef < template T >
struct a_metafun<T, true> { typedef typename T::type type };
在观看14.8.2(C++ 03),它看起来对我来说,它仅指定了下情况SFINAE可以申请什么。有更好的地方看吗?在已经推导出的模板的实例化中失败,即使在扣除另一个模板的过程中,似乎也不包括在这个列表中。
我已经采取了另一个解释是什么使得这个非法的方向是a_metafun的演绎已经发生并且其内部的实例化是导致错误的原因。 SFINAE在实例化过程中不适用,但仅在扣除过程中使用,或者我错了吗?但在第二种情况下,a_metafun正确,并且实例化良好,但它内部没有“类型”定义,这意味着尝试实例化它的模板由于替换而失败。
基本上我想知道标准中的什么指定了我目睹的行为。我试过的每一个编译器都会抱怨,甚至是冒险岛。我认为他们这样做是正确的,我只是不完全确定为什么。
那么,专家......那是什么?为什么类型的实例化,即使在f()中的演绎上下文中导致错误而不是SFINAE排除?
我认为,应该在C++ 11失败,而不是在C++ 03虽然。 SFINAE规则(或者*措辞*)在C++ 11中略有改变。 – Nawaz