SFINAE:有些失败比其他失败更平等?

c-u*_*hin 5 c++ templates sfinae template-specialization

我正在尝试使用SFINAE来区分具有名为"name"的成员的类.我在似乎是标准模式的情况下进行了设置,但它没有工作 - 而不是默默地忽略'失败'替换,编译器会产生错误.

我确信我遇到了一些模板替换规则,如果有人能解释哪一个,我将不胜感激.

这是一个精简的例子.我正在使用gcc:

 template <typename U> string test( char(*)[sizeof(U::name)] = 0 ) { return "has name!"; }
 template <typename U> string test(...) { return "no name"; }

 struct HasName { string name; }
 struct NoName  {}

 cout << "HasName: " << test<HasName>(0) << endl;  //fine
 cout << "NoName: " << test<NoName>(0) << endl;    //compiler errors:

 //error: size of array has non-integral type `<type error>'
 //error: `name' is not a member of `NoName'
Run Code Online (Sandbox Code Playgroud)

Ste*_*sop 1

以下内容似乎有效(尽管正如迈克尔所说,它不一定会在其他编译器上给出您想要的结果):

#include <string>
#include <iostream>
using namespace std;

template <typename U> string test( char(*)[sizeof(U::name)] = 0 ) { return "has name!"; }
template <typename U> string test(...) { return "no name"; }

struct HasName { static string name; };
struct NoName  { };

 int main() {
    cout << "HasName: " << test<HasName>(0) << endl;
    cout << "NoName: " << test<NoName>(0) << endl;
}
Run Code Online (Sandbox Code Playgroud)

输出:

HasName: has name!
NoName: no name
Run Code Online (Sandbox Code Playgroud)

海湾合作委员会(GCC)4.3.4 20090804(发布)1

Comeau也接受该代码。