无法使用std :: basic_string推断模板参数

时间:2014-01-08 14:01:57

标签: c++ templates template-deduction

我的问题的条纹版本:

我想合并这两个函数:

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)

很抱歉。

2 个答案:

答案 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;
}

http://ideone.com/L63Gkn

处理模板参数时要小心。我还为wstring提供了一个小的重载,看看是否适合你。