无法在Visual Studio 10中编译SFINAE

时间:2011-01-26 15:20:31

标签: c++ c++11 visual-studio-2010

#include <iostream>
#include <vector>
#include <algorithm>
#include <utility>
#include <functional>
#include <type_traits>

struct X {};
struct Y {};

__int8 f(X x) { return 0; }
__int16 f(...) { return 0; }

template <typename T> typename std::enable_if<sizeof(f(T())) == sizeof(__int8), int>::type call(T const& t) {
    std::cout << "In call with f available";
    f(t);
    return 0;
}

template <typename T> typename std::enable_if<sizeof(f(T())) == sizeof(__int16), int>::type call(T const& t) {
    std::cout << "In call without f available";
    return 0;
}

int main() {
    Y y; X x;
    call(y);
    call(x);
}

这里似乎是一个非常简单的SFINAE用法,但编译器抛出一个错误,即它无法实例化enable_if<false, int>::type。有什么建议?显然这段代码在GCC上编译得很好(没有问哪个版本)。

编辑:此代码编译正确

#include <iostream>
#include <vector>
#include <algorithm>
#include <utility>
#include <functional>
#include <type_traits>

struct X {};
struct Y {};

__int8 f(X x) { return 0; }
__int16 f(...) { return 0; }

template<typename T> struct call_helper {
    static const int size = sizeof(f(T()));
};

template <typename T> typename std::enable_if<call_helper<T>::size == sizeof(__int8), int>::type call(T const& t) {
    std::cout << "In call with f available";
    f(t);
    return 0;
}

template <typename T> typename std::enable_if<call_helper<T>::size == sizeof(__int16), int>::type call(T const& t) {
    std::cout << "In call without f available";
    return 0;
}

int main() {
    Y y; X x;
    call(y);
    call(x);
}

所以我很高兴能把这一点当作一个bugarooney。

1 个答案:

答案 0 :(得分:2)

这在VS2010中编译并正常工作。使用David的建议修改。

#include <iostream>
#include <vector>
#include <algorithm>
#include <utility>
#include <functional>
#include <type_traits>

struct X {
  typedef X is_x;
  };
struct Y {};

__int8 f(X x) { return 0; }
__int16 f(...) { return 0; }

template < class T >
struct test {
  enum { result = sizeof(f(T())) };
  };

template <typename T>
typename std::enable_if< test<T>::result == sizeof(__int8), int>::type call(T const& t) {
    std::cout << "In call with f available" << std::endl;
    f(t);
    return 0;
}

template < typename T >
typename std::enable_if< test<T>::result == sizeof(__int16), int>::type call(T const& t) {
    std::cout << "In call without f available" << std::endl;
    return 0;
}

int main() {

    Y y; X x;
    call(y);
    call(x);
}