我发现模板特化存在很奇怪的问题。
这里:Type Traits - Explicit template specialization. fails on xcode
这里:C++ template specialization
据记载,成员函数模板特化必须在类外,但在同一命名空间中(是的,如果模板特化在类内,gcc 4.1.x 版本会失败并出现错误)。
因此,如果我将成员函数模板特化移动到类下面的同一命名空间中,那么 msvc-2010 编译器会认为我定义了它两次:我有编译器错误:
error LNK1169: one or more multiply defined symbols found
error LNK2005 with detail description of defining it twice.
如果我将同一命名空间下的模板特化移动到 cpp
文件中,则 msvc-2010 看不到它,并且在尝试对专用参数使用默认模板函数时会失败并出现多个错误:
error C2678: binary '>>' : no operator found which takes a left-hand operand of type 'std::istringstream' (or there is no acceptable conversion)
(发生错误是因为它尝试调用运算符 >> 到 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;
}
这个特化(来自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();
}
对 string
和 const char*
的专门化(正是为了避免 ss >> ret;
当 ret
为const char
指针)。
示例非常简单。
最佳答案
您可以将其放在类定义之外的 header 中,如下所示:
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();
}
或者使用您希望其具有的参数集声明常规方法,并像往常一样在 .cpp
中定义它:
.h
class MyMap
{
// ...
std::string getValue(std::string phrase, std::string def);
const char* getValue(std::string phrase, const char* def);
}
.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();
}
关于c++ - 在哪里放置模板特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35115239/