LINUX.ORG.RU

История изменений

Исправление robus, (текущая версия) :

[robus@ArchPortable ~]$ cat test.cpp 
#include <iostream>
#include <string>

template <typename String = std::string, typename Char = typename String::value_type>
void test1(const std::basic_string<Char>& s) {
        std::cout << "test1<Char> = " << s << std::endl;
}

template <typename String = std::string>
void test2(const std::basic_string<typename String::value_type>& s) {
        std::cout << "test2<typename String::value_type> = " << s << std::endl;
}

int main() {
        test1(std::string("test1"));
        test2("test2");
}

[robus@ArchPortable ~]$ g++ --version
g++ (GCC) 6.3.1 20170109
Copyright (C) 2016 Free Software Foundation, Inc.
Это свободно распространяемое программное обеспечение. Условия копирования
приведены в исходных текстах. Без гарантии каких-либо качеств, включая 
коммерческую ценность и применимость для каких-либо целей.

[robus@ArchPortable ~]$ g++ ./test.cpp -o ./test
[robus@ArchPortable ~]$ ./test 
test1<Char> = test1
test2<typename String::value_type> = test2

Но при этом

[robus@ArchPortable ~]$ cat test.cpp 
#include <iostream>
#include <string>

template <typename String = std::string, typename Char = typename String::value_type>
void test1(const std::basic_string<Char>& s) {
        std::cout << "test1<Char> = " << s << std::endl;
}

template <typename String = std::string>
void test2(const std::basic_string<typename String::value_type>& s) {
        std::cout << "test2<typename String::value_type> = " << s << std::endl;
}

int main() {
        test1("test1");
        test2("test2");
}

[robus@ArchPortable ~]$ g++ ./test.cpp -o ./test
./test.cpp: В функции «int main()»:
./test.cpp:15:15: ошибка: нет соответствующей функции для вызова «test1(const char [6])»
  test1("test1");
               ^
./test.cpp:5:6: замечание: candidate: template<class String, class Char> void test1(const std::__cxx11::basic_string<Char>&)
 void test1(const std::basic_string<Char>& s) {
      ^~~~~
./test.cpp:5:6: замечание:   вывод/подстановка аргумента шаблона неудачна:
./test.cpp:15:15: замечание:   несоответствие типов «const std::__cxx11::basic_string<Char>» и «const char [6]»
  test1("test1");
               ^

Т.е. аргумент имеет тип const char*, а не std::string, в результате фейлится дедукция типа шаблона.

Исходная версия robus, :

[robus@ArchPortable ~]$ cat test.cpp 
#include <iostream>
#include <string>

template <typename String = std::string, typename Char = typename String::value_type>
void test1(const std::basic_string<Char>& s) {
        std::cout << "test1<Char> = " << s << std::endl;
}

template <typename String = std::string>
void test2(const std::basic_string<typename String::value_type>& s) {
        std::cout << "test2<typename String::value_type> = " << s << std::endl;
}

int main() {
        test1(std::string("test1"));
        test2("test2");
}

[robus@ArchPortable ~]$ g++ --version
g++ (GCC) 6.3.1 20170109
Copyright (C) 2016 Free Software Foundation, Inc.
Это свободно распространяемое программное обеспечение. Условия копирования
приведены в исходных текстах. Без гарантии каких-либо качеств, включая 
коммерческую ценность и применимость для каких-либо целей.

[robus@ArchPortable ~]$ g++ ./test.cpp -o ./test
[robus@ArchPortable ~]$ ./test 
test1<Char> = test1
test2<typename String::value_type> = test2