ошибка C2784: не удалось вывести аргумент шаблона - PullRequest
3 голосов
/ 16 марта 2010

Все еще борюсь с шаблонами. В этом примере, несмотря на то, что скопировано прямо из книги, я получаю следующее сообщение об ошибке: Error 2 error C2784: 'IsClassT<T>::One IsClassT<T>::test(int C::* )' : could not deduce template argument for 'int C::* ' from 'int'.

Это пример из книги Шаблоны - Полное руководство . (Я работаю с Visual Studio 2010 RC).

  template<typename T> 
    class IsClassT { 
      private: 
        typedef char One; 
        typedef struct { char a[2]; } Two; 
        template<typename C> static One test(int C::*); 
        template<typename C> static Two test(…); 
      public: 
        enum { Yes = sizeof(IsClassT<T>::test<T>(0)) == 1 }; 
        enum { No = !Yes }; 
    }; 

class MyClass { 
}; 

struct MyStruct { 
}; 

union MyUnion { 
}; 

void myfunc() 
{ 
} 

enum E {e1} e; 

// check by passing type as template argument 
template <typename T> 
void check() 
{ 
    if (IsClassT<T>::Yes) { 
        std::cout << " IsClassT " << std::endl; 
    } 
    else { 
        std::cout << " !IsClassT " << std::endl; 
    } 
} 

// check by passing type as function call argument 
template <typename T> 
void checkT (T) 
{ 
    check<T>(); 
} 

int main() 
{ 
    /*std::cout << "int: "; 
    check<int>(); */

    std::cout << "MyClass: "; 
    check<MyClass>(); 
}

И хотя я примерно знаю, что происходит в этом примере, я не могу исправить эту ошибку.
Спасибо за помощь.

Ответы [ 3 ]

5 голосов
/ 16 марта 2010

Моему компилятору (MSVC2008TS) понравится, если вы не полностью определите выражение test:

enum { Yes = sizeof(test<T>(0)) == 1 }; 

Но это даже юридический код?

3 голосов
/ 16 марта 2010

Разве эта строка не должна

    enum { Yes = sizeof(IsClassT<T>::test<T>(0)) == 1 }; 

быть

    enum { Yes = sizeof(IsClassT<T>::template test<T>(0)) == 1 }; 

вместо этого? `

(А поскольку я анальный, я бы написал sizeof(IsClassT<T>::template test<T>(0)) == sizeof(One).)

1 голос
/ 17 марта 2010

Не совсем ответ на этот вопрос, а скорее другой подход к вашей проблеме. Мне легче выполнять тесты SFINAE по специализациям, а не по функциям, определенным в этом шаблоне:

// used to pass a type tested with SFINAE
template<typename T> struct tovoid { typedef void type; };

Использование его для передачи типа, который может быть недействительным:

template<typename T, typename U = void> 
struct is_class {
  static bool const value = false;
};

// if "int T::*" is a valid type, this specialization is used
template<typename T>
struct is_class<T, typename tovoid<int T::*>::type> {
  static bool const value = true;
};

Таким образом, он значительно короче, а шум с sizeof и ничего не сделано.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...