MSVC 2013 'type': 不是 'std::enable_if<false,void> 的成员
MSVC 2013 'type' : is not a member of 'std::enable_if<false,void>
我使用 std::enable_if
的 SFINAE 代码可以在 GCC 和 Clang 中编译,但不能在 MSVC 2013 中编译。
#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 上看到过一些类似的问题,但是 none 有一个明确的答案或者有点切题。
正在阅读 MSVC enable_if 页面,这应该可行...
如何在 MSVC2013 中使用 SFINAE?
更新
请注意,这在肯定的情况下确实有效。例如,如果我注释掉第一个函数和对它的调用,那么其余的都会编译。即 CallDoDataProcessing
上的 enable_if<true, void>
确实有一个 type
成员。
但是,注释掉第二个函数并调用它(因此,保留 sizeof...(AdditionalInputs) == 0
不起作用的版本。同样的错误。
这表明 sizeof...(AdditionalInputs) == 0
调用不匹配,但我不明白为什么不匹配。
尝试标签调度。
template<std::size_t>
struct size {};
namespace details {
template <typename T, typename ... AdditionalInputs>
void CallDoDataProcessing(T var, size<0>) {
std::cout << sizeof...(AdditionalInputs) << ", aka 0, additional inputs" << std::endl;
}
template <typename T, typename ... AdditionalInputs, std::size_t N>
void CallDoDataProcessing(T var, size<N>) {
std::cout << sizeof...(AdditionalInputs) << " additional inputs" << std::endl;
}
}
template <typename T, typename ... AdditionalInputs>
void CallDoDataProcessing(T var) {
details::CallDoDataProcessing<T, AdditionalInputs>( var, size<sizeof...(AdditionalInputs)>{} );
}
SFINAE 对 MSVC 的支持真的很差。您的代码看起来像有效的 SFINAE。 MSVC 没有做正确的事这一事实并不奇怪。
根据我的经验,MSVC 在标记分派方面好得多,我发现它甚至可以使代码更容易理解,有时甚至会产生错误消息。
它不允许的是在调用函数的主体之前注意 "no, you cannot do this",使调用函数也状态为 "no, I cannot be done".
我使用 std::enable_if
的 SFINAE 代码可以在 GCC 和 Clang 中编译,但不能在 MSVC 2013 中编译。
#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 上看到过一些类似的问题,但是 none 有一个明确的答案或者有点切题。
正在阅读 MSVC enable_if 页面,这应该可行...
如何在 MSVC2013 中使用 SFINAE?
更新
请注意,这在肯定的情况下确实有效。例如,如果我注释掉第一个函数和对它的调用,那么其余的都会编译。即 CallDoDataProcessing
上的 enable_if<true, void>
确实有一个 type
成员。
但是,注释掉第二个函数并调用它(因此,保留 sizeof...(AdditionalInputs) == 0
不起作用的版本。同样的错误。
这表明 sizeof...(AdditionalInputs) == 0
调用不匹配,但我不明白为什么不匹配。
尝试标签调度。
template<std::size_t>
struct size {};
namespace details {
template <typename T, typename ... AdditionalInputs>
void CallDoDataProcessing(T var, size<0>) {
std::cout << sizeof...(AdditionalInputs) << ", aka 0, additional inputs" << std::endl;
}
template <typename T, typename ... AdditionalInputs, std::size_t N>
void CallDoDataProcessing(T var, size<N>) {
std::cout << sizeof...(AdditionalInputs) << " additional inputs" << std::endl;
}
}
template <typename T, typename ... AdditionalInputs>
void CallDoDataProcessing(T var) {
details::CallDoDataProcessing<T, AdditionalInputs>( var, size<sizeof...(AdditionalInputs)>{} );
}
SFINAE 对 MSVC 的支持真的很差。您的代码看起来像有效的 SFINAE。 MSVC 没有做正确的事这一事实并不奇怪。
根据我的经验,MSVC 在标记分派方面好得多,我发现它甚至可以使代码更容易理解,有时甚至会产生错误消息。
它不允许的是在调用函数的主体之前注意 "no, you cannot do this",使调用函数也状态为 "no, I cannot be done".