我有一个模板化的课程
template <typename T>
class Factors
{
public:
Factors(){};
deque<string> stringsDeck;
// some methods and variables here
map <string, string> getNext();
};
getNext
方法将用作键的字符串与用作值的stringsDeck
字符串组合在一起,并返回map <string,string>
。
如果我已经模板化stringify
和string2num
函数,我希望有一个方法map<string,Scalar> getNext()
,除了字符串之外的其他每种类型都会将地图的值转换为指定的模板类型T
。
编译器不允许我重载具有相同名称但具有不同返回类型的两个方法,具体为:
map <string, T > getNext()
{
// converts the values of getNext() return map into the specified type T
return convertedMapWithValuesOfTypeT;
}
在这种情况下可以解决什么问题?我想保持方法的名称与字符串和其他类型相同(基本上是可以通过词法转换从字符串转换的数字类型)
答案 0 :(得分:4)
语言不允许功能过载,这些功能只有不同 返回类型,因为在大多数情况下,不考虑返回类型 功能重载决议。在这种情况下,你真的有三个 可能的解决方案:
getNextAsMapToType
和
例如getNextAsMapToString
。template<typename U> std::map<string, U> getNext();然后,将此函数专门用于
std::string
和
T
(和
没有其他的)。用户必须指定
getNext<std::string>()
或getNext<...>
给他想要的人打电话。
一般来说,我会发现它的可读性远远低于
以前的解决方案,但它可能适用于模板,其中
名称应包含或至少建议类型的名称。
getNext()
函数必须返回一个
代理,具有重载转换函数,类似于:
class Proxy { Factors* myOwner; public: Proxy( Factors& owner ) : myOwner( &owner ) {} operator std::map<std::string, std::string>() const { return myOwner->getNextAsMapToString(); } operator std::map<std::string, T>() const { return myOwner->getNextAsMapToType(); } }; Proxy getNext() { return Proxy( *this ); }然后,客户端代码可以只调用
getNext()
,具体取决于它们
做结果,getNextAsMapToString
或
getNextAsMapToType
将被调用。
答案 1 :(得分:0)
您可以使用[getNext
]在typeid
中添加运行时检查
(http://en.cppreference.com/w/cpp/language/typeid)查看T
是否为字符串。
类似的东西:
template <typename T>
class Factors
{
public:
Factors(){};
deque<string> stringsDeck;
// some methods and variables here
map <string, T> getNext();
{
if (typeid(T) == typeid(string))
{
// Special handling for strings
}
else
{
// Do something else for other types
}
}
};
正如fschoenm所说,模板专业化可能更好:
template <typename T>
class Factors
{
public:
Factors(){};
// some methods and variables here
map <string, T> getNext();
};
template <>
class Factors<string>
{
public:
Factors(){};
deque<string> stringsDeck;
// some methods and variables here
map <string, string> getNext();
};