C++ 为什么dllexport编译不是专门的模板成员函数?
我有一个基类模板,它有两个参数,T是派生类,标志表示我想激活某些功能,默认为false:C++ 为什么dllexport编译不是专门的模板成员函数?,c++,templates,inheritance,dllexport,C++,Templates,Inheritance,Dllexport,我有一个基类模板,它有两个参数,T是派生类,标志表示我想激活某些功能,默认为false: template < typename T, bool flag > class SomeBase { public: static Info& GetInfo() { static Info& instance = CreateInfo<T>(T::ClassName()); static bool
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);
}
};
模板
<
类型名T,
布尔旗
>
类SomeBase
{
公众:
静态信息&GetInfo()
{
静态信息&instance=CreateInfo(T::ClassName());
静态bool inited=false;
如果(!inited)
{
测试(实例);
inited=true;
}
返回实例;
}
私人:
样板
静态无效测试(信息和实例)
{
回来
}
样板
静态无效测试(信息和实例)
{
T::添加(字段);
}
};
要使用此基础:
class /*dllexport*/ MyClass : public SomeBase<MyClass, false>
{
public:
// ...
};
class/*dllexport*/MyClass:publicsomebase
{
公众:
// ...
};
flag
template参数设置为false,因此根据我的专业化,它应该编译上面的空函数,然后由编译器执行,这很好
但是,如果我将dllexport
添加到MyClass
,那么编译器会给出C2039,这表示'add'不是MyClass
的成员,这没有意义,因为我使用SomeBase
作为标志==false
为什么添加dllexport
会使编译器尝试编译错误的专门化?
////////////////////////////////////////编辑1:
////////////////////////////////////////
根据这个链接: 当一个或多个基类是类模板的特化时,语句
是否在谈论SomeBase
如果是这样,编译器将dllexport隐式应用于类模板的专门化
表示编译器正在将dllexport
添加到SomeBase
而且,由于我已经完全专门化了静态无效测试(Info&instance)
,编译器应该选择正确版本的Test()
,即Test()
那么,为什么它选择(或编译)了错误的版本(Test()
)
谢谢 如果没有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;
}
模板
类SomeBase
{
公众:
无效测试()
{
dafsaf;
}
私人:
};
class/*\uu declspec(dllexport)*/MyClass:public SomeBase
{
公众:
// ...
};
int main()
{
MyO类;
//o、 test();
返回1;
}
我认为在模板类上使用dllexport没有多大意义。无论如何,在使用时都需要有完整的头文件。编译器可能试图为链接器创建类的完整定义,但这样做行不通。您好,我是dllexport
ingMyClass
,而不是SomeBase
MyClass
不是一个类模板,对吗?没有dllexport我就没有错误:/你说“它扩展并编译所有东西”,有没有提到过这种行为?谢谢您可以参考这个链接,搜索并阅读“编译器隐式地将dllexport应用于类模板的专门化”嗨,我已经读过了,但不太清楚它的意思。当一个或多个基类是类模板的特化时,语句是否在谈论SomeBase
?如果是这样,编译器隐式地将dllexport应用于类模板的专门化
意味着编译器正在将dllexport
添加到SomeBase
,并且,由于我已经完全专门化了静态无效测试(信息和实例)
,编译器应该选择正确版本的Test()
。那么,它为什么选择(或编译)了错误的版本呢?