Не могу скомпилировать SFINAE в Visual Studio 10 - PullRequest
4 голосов
/ 26 января 2011
#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);
}

Так что я очень рад, что записал это как бугруни.

1 Ответ

2 голосов
/ 26 января 2011

Это компилируется и работает правильно в VS2010. Модифицировано по предложению Дэвида.

#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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...