尝试编译 SFINAE 检查中使用的方法主体时出现编译错误

Compilation error when trying to compile body of a method used in SFINAE checks

我有一个著名的 class 示例,它检测类型是否为 class。

#include <cstdio>
#include <type_traits>

template <typename T>                                        
class ClassDetector {
private:
    typedef char One;
    typedef struct { char a[2]; } Two;

    template <typename C> static One test(int C::*) {
        compilation error;
    }

    template <typename C> static Two test(...);

public:
    enum { Yes = sizeof(ClassDetector<T>::test<T>(0)) == 1 };
    enum { No = !Yes };
};

int main() {
    printf("%d\n", ClassDetector<int>::Yes);
    return 0;
}

代码无法在 GCCClang 上编译,因为 "compilation error" 未在任何地方定义,编译器不知道它是什么。但它在 Visual Studio 下有效。这表明 Visual Studio 完全跳过了第一个 test 方法的主体,甚至不检查内部的任何内容。

所以,问题是:在这种情况下谁是对的? GCC/Clang 还是VS?是否应该检查该方法是否存在编译错误,或者这不是必需的并且不是由标准强制执行的?

很可能您在 VS 中使用允许模式构建,该模式禁用两阶段查找(最近已实现)。 Disabling permissive mode by specifying /permissive- argument will cause compilation in VS to fail as well.