所以我得到了一个类,它为每种类型指定了一个具有特殊含义的常量。 我用这样的东西
template<class Type>
class SpecialKeyProvider
{
static const Type SPECIAL_KEY;
}
具有一个或多个类型的特化,这些类型也将被使用但不是数字。 所以我在类的定义之外初始化静态成员,就像我必须做的那样:
// This seems to have to be in a cpp as having it in the same header,
// will result in duplicate definitions of SPECIAL_KEY;
// This particular instantiation is kind of problematic anyways, see
// the end of my question for another question on this one.
template<>
string SpecialKeyProvider<string>::SPECIAL_KEY = "__SPECIAL";
template <class Type>
Type SpecialKeyProvider<Type> = std::numeric_limits<Type>::max();
不幸的是,SpecialKeyProvider 被用在一个非常核心的 Container 类中。该容器有许多出于性能原因应内联的方法,并在许多地方使用。所以我把整个容器放在了头文件中。但现在使用了 SpecialKeyProvider,我仍然必须将 SpecialKeyProvider.o 链接到我项目中的几乎每个二进制文件。
有什么方法可以摆脱这种情况并在 header 中进行模板特化,而不会因“多重定义”而出现错误?
关于字符串常量的第二个问题。
// I know this is bad code but I don't know how to do it better.
template<>
string SpecialKeyProvider<string>::SPECIAL_KEY = "__SPECIAL";
我知道(并且 linter 提醒我),由于不确定的构造顺序 ( google style guide ),尤其是字符串,使用任何类类型的常量通常不是一个好主意。虽然我通常可以改用 const char[],但我不知道在这种情况下该怎么做,因为我希望为字符串实例化模板。使用带有 char* 的模板(即使用我的使用 SpecialKeyProvider 的容器类)会非常痛苦。
非常感谢您的建议。
最佳答案
将带有static const
的class
放在头文件的未命名空间 中:
namespace
{
template<class Type>
class SpecialKeyProvider
{
static const Type SPECIAL_KEY;
};
template<>
const string SpecialKeyProvider<string>::SPECIAL_KEY = "__SPECIAL"; //<--- const
template<>
const double SpecialKeyProvider<double>::SPECIAL_KEY = 3.3; //<--- const
}
即使您在头文件中声明变量,也不会导致任何链接器错误;因为对于每个 .cpp
文件,都会创建一个不同的未命名 namespace
。对于您的情况,您只声明了 const
变量,因此可以确保所有 .cpp 文件都读取相同的值。
编辑:关于你的第二个问题,我不知道上面的方法有什么问题,因为每个翻译单元都会创建一个不同的 const
拷贝.查看 lint 是否仍然报错。
关于c++ - 如何避免到处链接某个目标文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6716408/