我的问题的条纹版本:
我想合并这两个函数:
void Bar(const std::string &s);
void Bar(const std::wstring &s);
..进入一个模板化函数:
template <class CharType>
void Foo(const std::basic_string<CharType> &s);
而且我认为我可以像Foo
和(1)
一样致电(2)
,但令我惊讶的是,(3)
工作都没有。
(1) Foo("my string");
(2) Foo(std::string("my string"));
(3) Foo(std::basic_string<char>("my string"));
我尝试删除参数const
的{{1}}限定符,甚至删除引用(s
),或使用&
而不是lvalues
进行调用,但是都具有相同的结果。
编译器(gcc和VS - 所以我很确定它是符合标准的行为)不能推导出rvalues
的模板参数。当然,如果我将Foo
称为Foo
,那么它就可以了。
所以我想理解为什么会这样,特别是因为调用Foo<char>(...)
是调用参数对象的类型和函数参数类型之间的一对一类型。
其次,我想要一个解决方法:能够使用一个模板化函数,并能够像(3)
和(1)
一样调用它。
修改
(2)
和(2)
可以正常运作。我在编译器中声明它是错误的(不像我的问题):
(3)
很抱歉。
答案 0 :(得分:3)
基本字符串模板如下所示:
template<
class CharT,
class Traits = std::char_traits<CharT>,
class Allocator = std::allocator<CharT>
> class basic_string;
所以你需要将你的函数声明为
template <typename CharType, typename CharTrait, typename Allocator>
void Foo(const std::basic_string<CharType, CharTrait, Allocator> &s);
要匹配(可以推导出所有模板类型参数,所以我认为你不需要复制函数中的默认值。)
答案 1 :(得分:3)
1)将无效,因为您尝试使用 const char [10] 而不是std :: string
2)应该工作,因此应该3)因为默认模板参数应该确保你使用默认值
#include <iostream>
using namespace std;
template <class CharType>
void Foo(const std::basic_string<CharType> &s)
{
cout << s.c_str(); // TODO: Handle cout for wstring!!!
}
void Foo(const char *s)
{
Foo((std::string)s);
}
int main()
{
std::wstring mystr(L"hello");
Foo(mystr);
Foo("world");
Foo(std::string("Im"));
Foo(std::basic_string<char>("so happy"));
return 0;
}
处理模板参数时要小心。我还为wstring提供了一个小的重载,看看是否适合你。