История изменений
Исправление 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