在哪里放置模板专业化

Ark*_*ady 2 c++ gcc templates visual-studio-2010

我发现模板专业化存在很奇怪的问题。

此处:类型特征 - 显式模板专业化。在 xcode 上失败

这里: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指针)。

示例非常简单。

Pat*_*ryk 5

您可以将其放在类定义之外的标头中,如下所示:

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)