Я пытаюсь скомпилировать 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
};