2014-01-08 8 views
0

полосатой вниз версии моей проблемы:Не удалось вывести аргумент шаблона с станд :: basic_string

Я хочу объединить эти две функции:

void Bar(const std::string &s); 
void Bar(const std::wstring &s); 

..into одной шаблонных функции:

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 спецификатор для параметра s и даже опуская ссылку (&), или позвонив по телефону с lvalues вместо rvalues, но все с тем же результатом.

Компилятор (как gcc, так и VS - так что я уверен, что это стандартное совместимое поведение) не может вывести аргумент шаблона для Foo. Конечно, он работает, если я позвоню Foo, например Foo<char>(...).

Так что я хотел бы понять, почему это происходит, тем более, что вызов (3) является взаимно однозначным типом между типом вызывающего параметра и типом аргумента функции.

Во-вторых, мне бы хотелось обходным путем: чтобы использовать одну шаблонную функцию, и иметь возможность называть ее как (1) и (2).

Редактировать

(2) и (3) работают. Я заявляю, что это неправильно в моем компиляторе (не так, как в моем вопросе):

template <class CharType> 
    void Foo(const std::basic_string<char> &s); 

Извините.

+0

Насколько я могу видеть в реализации VS в 'станд :: string' не на самом деле' 'basic_string является' basic_string <голец, char_traits , Распределитель > ', так что я думаю, что это не работает, потому что не хватает какой-то аргументы шаблона. – Raxvan

+0

Отредактировал свой ответ, может подойти вам сейчас –

ответ

3

1) не будет работать, потому что вы пытаетесь использовать константный символ [10] вместо станд :: строка

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, посмотрим, подходит ли это вам.

+0

Бог, я объявлял это как 'template void Foo (const std :: basic_string & s)'. Я отредактирую свой вопрос. Спасибо. – bolov

+0

Это нормально, я не использую свою функцию для записи в потоки. В моей реальной функции у меня есть более строковые аргументы, и я генерирую и возвращаю новую строку. – bolov

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); 

для того, чтобы соответствовать (все параметры типа шаблона могут быть выведены, поэтому я не Думаю, вам нужно реплицировать значения по умолчанию в вашей функции).

+0

Я подтверждаю, что репликация значений по умолчанию в функции бесполезна; когда аргумент 's' выведен для соответствия шаблону' std :: basic_string <...> const & ', тогда все параметры шаблона также выводятся. –