我有一个基类模板,它有2个参数,T是派生类,flag表示我想激活某个功能,默认为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 :(得分:0)
如果没有dllexport,当您从main调用MyClass :: GetInfo时,您将收到相同的错误。 在这种情况下,编译器正在扩展并仅编译调用的部分代码。 但是使用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;
}