Ark*_*ady 2 c++ gcc templates visual-studio-2010
我发现模板专业化存在很奇怪的问题。
这里:C++ 模板专业化
据记载,成员函数模板特化必须在类之外,但在相同的命名空间中(是的,如果模板特化在类内部,gcc 4.1.x 版本会失败并出现错误)。
因此,如果我将成员函数模板专业化移动到类下面的同一命名空间中,那么 msvc-2010 编译器会认为我定义了它两次:我有编译器错误:
错误LNK1169:找到一个或多个多重定义的符号
错误LNK2005及其定义两次的详细描述。
如果我将同一命名空间下的模板专业化移动到cpp文件中,则 msvc-2010 看不到它,并且在尝试对专用参数使用默认模板函数时会失败并出现多个错误:
错误 C2678:二进制“>>”:找不到采用“std::istringstream”类型的左侧操作数的运算符(或者没有可接受的转换)
(发生错误是因为它尝试调用运算符 >> 到 const char 指针)
因此,当模板专门化位于类内部时,msvc-2010 对我有用,但 gcc-4.1.x 不起作用。
最后,我应该在哪里放置模板专门化,以便能够在两个编译器中编译它?
那是标题:
#include <iostream>
#include <sstream>
#include <string>
class MyMap
{
public:
template<typename T>
T getValue(std::string phrase, T def)
{
std::istringstream ss(phrase);
T ret;
ss >> ret;
if(ss.fail() || !ss.eof())
return def;
else
return ret;
}
Run Code Online (Sandbox Code Playgroud)
而这个专业化(来自cpp,但我不知道它必须在哪里):
template<>
std::string MyMap::getValue(std::string phrase, std::string def)
{
return phrase;
}
template<>
const char* MyMap::getValue(std::string phrase, const char* def)
{
return phrase.c_str();
}
Run Code Online (Sandbox Code Playgroud)
stringand的特化const char*(正是为了避免ss >> ret;when retisconst char指针)。
示例非常简单。
您可以将其放在类定义之外的标头中,如下所示:
template<>
inline std::string MyMap::getValue<std::string>(std::string phrase, std::string def)
{
return phrase;
}
template<>
inline const char* MyMap::getValue<const char*>(std::string phrase, const char* def)
{
return phrase.c_str();
}
Run Code Online (Sandbox Code Playgroud)
或者使用您希望其具有的参数集声明常规方法,并像.cpp往常一样在中定义它:
。H
class MyMap
{
// ...
std::string getValue(std::string phrase, std::string def);
const char* getValue(std::string phrase, const char* def);
}
Run Code Online (Sandbox Code Playgroud)
.cpp
std::string MyMap::getValue(std::string phrase, std::string def)
{
return phrase;
}
const char* MyMap::getValue(std::string phrase, const char* def)
{
return phrase.c_str();
}
Run Code Online (Sandbox Code Playgroud)