Это FAQ, но я не смог найти удовлетворительного ответа. В моем проекте мы поддерживаем std::string
и теперь также должны поддерживать широкие строки. Поэтому мы хотим, чтобы перейти к basic_string
, но потом, все перестанет работать хорошо и параметры должны быть прописаны в явном виде:basic_string <CharT> vs. CharT *
#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>&)
^
Что Я не понимаю, почему он работает для bar
? Почему для решения этой проблемы недостаточно явного создания экземпляра foo
для char
(либо с явными параметрами шаблона, либо с вычитанием)?
Кажется, что это означает, что вместо того, чтобы использовать шаблоны и basic_string
в облученной API, мы будем использовать его в качестве детали реализации, но выставить пользователь перегрузок для std::string
, std::wstring
и т.д., которая является позором.
Спасибо!
е xclicit версия 'foo' работает с clang3.5, только ошибка с выводом параметра (последняя строка), потому что она не может выводить параметр. – Drax