Почему dllexport компилирует не специализированный шаблон-функцию?

У меня есть шаблон базового класса, который имеет 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>())?

Спасибо!

0

Решение

Без 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;
}
0

Другие решения


По вопросам рекламы [email protected]