【发布时间】:2017-01-27 11:57:16
【问题描述】:
我使用 std::enable_if 的 SFINAE 代码在 GCC 和 Clang 中编译,但在 MSVC 2013 中不编译。
代码 (also available on cpp.sh) 是
#include <iostream>
#include <type_traits>
template <typename T, typename ... AdditionalInputs>
typename std::enable_if<sizeof...(AdditionalInputs) == 0, void>::type
CallDoDataProcessing(T var) {
std::cout << sizeof...(AdditionalInputs) << " additional inputs" << std::endl;
}
template <typename T, typename ... AdditionalInputs>
typename std::enable_if<sizeof...(AdditionalInputs) == 1, void>::type
CallDoDataProcessing(T var) {
std::cout << sizeof...(AdditionalInputs) << " additional inputs" << std::endl;
}
int main() {
CallDoDataProcessing<int>(3);
CallDoDataProcessing<int, int>(3);
return 0;
}
在 GCC/Clang 中,这非常有效,但在 MSVC 中,我得到:
Error 1 error C2039: 'type' : is not a member of 'std::enable_if<false,void>' c:\Users\mrussell\documents\visual studio 2013\Projects\ConsoleApplication1\ConsoleApplication1\ConsoleApplication1.cpp 5 1 ConsoleApplication1
编译和运行的输出应该是:
0 additional inputs
1 additional inputs
我在 SO 上看到过一些类似的问题,但没有一个有明确的答案或有点切题。
阅读MSVC enable_if 页面,这应该可以工作...
如何在 MSVC2013 中使用 SFINAE?
更新
请注意,这在积极的情况下确实有效。例如,如果我注释掉第一个函数以及对它的调用,那么其余的都会编译。即CallDoDataProcessing 上的enable_if<true, void> 确实有一个type 成员。
但是,注释掉第二个函数并调用它(因此,保留 sizeof...(AdditionalInputs) == 0 不起作用的版本。同样的错误。
这表明 sizeof...(AdditionalInputs) == 0 调用不匹配,但我不知道为什么不匹配。
【问题讨论】:
-
你
#include <type_traits>了吗? -
@AndyG 从来没有想过,我只是尝试了一下,但似乎并没有什么不同。我将修改上面的代码以显示包含。
-
我的第一个猜测是你需要更新 MSVC
-
@Matt:是的,这似乎是 SFINAE 的一个错误。我可以重现它。它在 VS 2015 中似乎已修复。
-
MSVC 错误除外,第一个重载格式不正确,不需要诊断,因为它的每个有效特化都需要一个空参数包。
标签: c++ c++11 visual-studio-2013 variadic-templates sfinae