无法推断出basic_string的模板参数

时间:2017-11-13 21:49:03

标签: c++ templates

我的代码中有这个函数定义:

template <
    class CharT,
    class Traits = std::char_traits<CharT>, 
    class Allocator = std::allocator<CharT>
> std::basic_string<CharT, Traits, Allocator> bytes2string(const Bytes& bytes)
{
     // do work ...
}

当我尝试这样调用函数时:

int main()
{
    Bytes bytes{'H', 'e', 'l', 'l', 'o'};

    std::string str = bytes2string(bytes); // error

    return 0;
}

我遇到以下错误:

error: 
      no matching function for call to 'bytes2string'

note: 
  candidate template ignored: couldn't infer template argument 'CharT'
> std::basic_string<CharT, Traits, Allocator> bytes2string(const Bytes& bytes)

我很确定它应该可行但是唉,它没有。如果有人想知道,Bytes也只是std::vector<char>

2 个答案:

答案 0 :(得分:4)

仔细看看你的签名:

template <
    class CharT,
    class Traits = std::char_traits<CharT>, 
    class Allocator = std::allocator<CharT>
> std::basic_string<CharT, Traits, Allocator> bytes2string(const Bytes& bytes);

没有任何内容可以推导出CharT - 它需要由用户明确提供。

std::string str = bytes2string(bytes);

不幸的是,C ++没有Hindley-Milner类型推断 - 不可能以这种方式推断返回类型的模板参数。函数模板参数只能通过传递给函数的参数推断出来。

如果您将签名更改为:

template <
    class CharT,
    class Traits = std::char_traits<CharT>, 
    class Allocator = std::allocator<CharT>
> void bytes2string(std::basic_string<CharT, Traits, Allocator>& out, const Bytes& bytes);

并调用:

std::string str;
bytes2string(str, bytes);

将推断出您的模板参数。

live example on wandbox

答案 1 :(得分:2)

如果函数应该返回std::string,那么就这样写:

std::string bytes2string(const Bytes& bytes);

如果它应该能够生成std::basic_string的任意实例化,那么您需要提供适当的模板参数。通常通过传入适当类型的字符串来完成。这似乎不合适,因为除了提供模板参数之外,传递字符串没有明显的用途。

另一种方法是在通话时命名相应的类型:

std::string str = bytes2string<char>(bytes);