aki*_*kim 3 c++ templates stdstring c++11 type-deduction
这是一个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");
}
Run Code Online (Sandbox Code Playgroud)
好吧,由于众所周知的原因,它失败了:
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>&)
^
Run Code Online (Sandbox Code Playgroud)
我不明白它为什么适用bar?为什么foofor 的显式实例化char(无论是使用显式模板参数还是使用演绎)都足以解决这个问题?
看来,这意味着,而不是使用模板和basic_string公开的API中,我们将使用它作为一个实现细节,但重载暴露用户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>>&);
Run Code Online (Sandbox Code Playgroud)
隐式转换开始了,一切都很好.
第三个电话不提供模板参数,所以编译器必须弄清楚的类型CharT,Traits并Allocator从类型char const[4].此类型不携带该信息,因此扣除失败,重载解析无法找到正确的功能.
| 归档时间: |
|
| 查看次数: |
515 次 |
| 最近记录: |