c – basic_string与CharT *
作者:互联网
这是一个FAQ,但我找不到令人满意的答案.在我的项目中,我们支持std :: string,现在还必须支持宽字符串.所以我们想转移到basic_string,但是,事情就会停止工作,并且需要明确地拼写参数:
#include <string>
template <typename CharT, typename Traits, typename Allocator>
void
foo(const std::basic_string<CharT, Traits, Allocator>&)
{}
template void foo(const std::string&);
// template void
// foo<char, std::char_traits<char>, std::allocator<char>>(const std::string&);
void bar(const std::string& s)
{}
int main()
{
bar("abc");
foo<char, std::char_traits<char>, std::allocator<char>>("def");
foo("def");
}
好吧,由于众所周知的原因,它失败了:
clang++-mp-3.5 -Wall -std=c++11 foo.cc
foo.cc:20:3: error: no matching function for call to 'foo'
foo("def");
^~~
foo.cc:5:1: note: candidate template ignored: could not match
'basic_string<type-parameter-0-0, type-parameter-0-1, type-parameter-0-2>'
against 'char const[4]'
foo(const std::basic_string<CharT, Traits, Allocator>&)
^
我不知道为什么它适用于酒吧?为什么不为char显式实例化foo(使用显式模板参数或使用演绎)是否足以解决此问题?
看来这意味着我们不得不在暴露的API中使用模板和basic_string,而是将它用作实现细节,但是为std :: string,std :: wstring等提供了重载的用户,这是一个耻辱.
谢谢!
解决方法:
对于bar(“abc”),存在从char const [4]到std :: string的隐式转换. foo与bar的不同之处在于它实际上不是函数而是函数模板.需要知道其模板参数才能构建正确的函数.
对foo的第一次调用显式提供了模板参数,因此它构建了一个如下所示的函数:
void foo(const std::basic_string<char, std::char_traits<char>, std::allocator<char>>&);
隐式转换开始了,一切都很好.
第三个调用不提供模板参数,因此编译器必须从char const [4]类型中找出CharT,Traits和Allocator的类型.此类型不携带该信息,因此扣除失败,重载解析无法找到正确的功能.
标签:type-deduction,c,c11,templates,stdstring 来源: https://codeday.me/bug/20190722/1505915.html