MSVC: неявное создание шаблона, хотя шаблонный конструктор не используется - PullRequest
1 голос
/ 02 августа 2010

Я пытаюсь скомпилировать Flusspferd в Windows, используя MSVC, но это не удается из-за проблемы с созданием шаблона.Для простоты объяснения я переписал проблему в более простых терминах:

#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_convertible.hpp>

class UndefinedType;

class A
{

};

class TestClass {

public:

    TestClass(A* a)
    {

    }

    template<typename OtherType>
    TestClass(OtherType t, typename boost::disable_if<typename boost::is_convertible<OtherType, UndefinedType>::type>::type * = 0)
    {

    }
};

Проблема в том, что TestClass содержит шаблонный конструктор, который использует boost :: is_convertible с перенаправленным классом UndefinedType.is_convertible работает только для полных типов, то есть этот конструктор следует использовать только в том случае, если определен UndefinedType, в противном случае создание экземпляра шаблона завершится неудачно с C2139.

В Flusspferd TestClass используется в местах, где UndefinedType не был определен, но с использованием своего другого конструктора:

void test()
{
    A* a = new A();
    TestClass test(a); // will instantiate the templated constructor, but why?
}

Хотя TestClass (A * a) является наиболее конкретным конструктором для этой ситуации, будет создан экземпляр шаблона, ведущий к C2139 из-за is_convertible.

GCC компилируется нормально, поэтому вопрос: почему не MSVC?Кто прав?Есть ли способ обойти это?

Спасибо за помощь!

Обновление:

MSalters правильно.Правильное поведение не определено.Из стандарта C ++:

Если процесс разрешения перегрузки может определить правильную функцию для вызова без создания экземпляра определения шаблона класса, неизвестно, имеет ли место эта реализация на самом деле.

template <class T> struct S {
    operator int();
};

void f(int);
void f(S<int>&);
void f(S<float>);

void g(S<int>& sr) {
    f(sr);  // instantiation of S<int> allowed but not required
            // instantiation of S<float> allowed but not required
};

1 Ответ

2 голосов
/ 02 августа 2010

Как вы утверждаете, "is_convertible работает только для полных типов". Это означает, что если вы нарушите это предварительное условие, может произойти все что угодно - в частности, неопределенное поведение. Таким образом, и GCC, и MSVC «правы» - они не обязаны создавать ни рабочий код, ни ошибки.

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