尝试编译 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;
}
代码无法在 GCC
和 Clang
上编译,因为 "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.
我有一个著名的 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;
}
代码无法在 GCC
和 Clang
上编译,因为 "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.