У меня есть шаблон базового класса, который имеет 2 параметра, T является производным классом, флаг означает, что я хочу активировать некоторую функцию, по умолчанию как false:
template
<
typename T,
bool flag
>
class SomeBase
{
public:
static Info& GetInfo()
{
static Info& instance = CreateInfo<T>(T::ClassName());
static bool inited = false;
if (!inited)
{
Test<flag>(instance);
inited = true;
}
return instance;
}
private:
template<bool enable>
static void Test(Info& instance)
{
return;
}
template<>
static void Test<true>(Info& instance)
{
T::Add(fields);
}
};
и использовать эту базу:
class /*dllexport*/ MyClass : public SomeBase<MyClass, false>
{
public:
// ...
};
flag
Параметр шаблона имеет значение false, поэтому, согласно моей специализации, он должен компилировать верхнюю пустую функцию, а компилятор это делает, что нормально.
Но, если я добавлю dllexport
в MyClass
Затем компилятор дает C2039, который говорит 'Add' is not a member of MyClass
, который не имеет смысла, потому что я использую SomeBase
как flag == false
,
Почему добавление dllexport
заставляет компилятор пытаться скомпилировать неправильную специализацию?
////////////////////////////////////////
Изменить 1:
////////////////////////////////////////
По этой ссылке:
http://msdn.microsoft.com/en-us/library/twa2aw10%28v=vs.100%29.aspx
Это заявление when one or more of the base classes is a specialization of a class template
говоря о SomeBase<MyClass, false>
?
Если так, the compiler implicitly applies dllexport to the specializations of class templates
означает, что компилятор добавляет dllexport
в SomeBase<MyClass, false>
,
И, так как я уже полностью специализирован static void Test(Info& instance)
, компилятор должен выбрать правильную версию Test()
, который Test<false>()
,
Так почему же он выбирает (или компилирует) неправильную версию?Test<true>()
)?
Спасибо!
Без dllexport вы получите ту же ошибку при вызове MyClass :: GetInfo из main.
В этом случае компилятор расширяет и компилирует только тот код, который вызывается.
Но с dllexport он расширяет и компилирует все.
Вы можете подтвердить это
template <typename T>
class SomeBase
{
public:
void test()
{
dafsaf;
}
private:
};
class /*__declspec(dllexport)*/ MyClass : public SomeBase<MyClass>
{
public:
// ...
};
int main()
{
MyClass o;
//o.test();
return 1;
}