LINUX.ORG.RU

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

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

Кажется я понял куда копать: template deduction не работает для «вложенных типов»:http://en.cppreference.com/w/cpp/language/template_argument_deduction

Non-deduced contexts
1) The nested-name-specifier (everything to the left of the scope resolution operator ::) of a type that was specified using a qualified-id:

// the identity template, often used to exclude specific arguments from deduction
template<typename T> struct identity { typedef T type; };
template<typename T> void bad(std::vector<T> x, T value = 1);
template<typename T> void good(std::vector<T> x, typename identity<T>::type value = 1);
std::vector<std::complex<double>> x;
bad(x, 1.2);  // P1 = std::vector<T>, A1 = std::vector<std::complex<double>>
              // P1/A1: deduced T = std::complex<double>
              // P2 = T, A2 = double
              // P2/A2: deduced T = double
              // error: deduction fails, T is ambiguous
good(x, 1.2); // P1 = std::vector<T>, A1 = std::vector<std::complex<double>>
              // P1/A1: deduced T = std::complex<double>
              // P2 = identity<T>::type, A2 = double
              // P2/A2: uses T deduced by P1/A1 because T is to the left of :: in P2
              // OK: T = std::complex<double>

... дедукция typename Char не происходит, т.к. он вложен в String и зависит от определеня String. Однако я еще не до конца не понимаю, почему параметр по умолчанию игнорируется (возможно из-за того, что была проба дедукции?).

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

Кажется я понял куда копать: template deduction не работает для «вложенных типов»:

1) The nested-name-specifier (everything to the left of the scope resolution operator ::) of a type that was specified using a qualified-id:

// the identity template, often used to exclude specific arguments from deduction
template<typename T> struct identity { typedef T type; };
template<typename T> void bad(std::vector<T> x, T value = 1);
template<typename T> void good(std::vector<T> x, typename identity<T>::type value = 1);
std::vector<std::complex<double>> x;
bad(x, 1.2);  // P1 = std::vector<T>, A1 = std::vector<std::complex<double>>
              // P1/A1: deduced T = std::complex<double>
              // P2 = T, A2 = double
              // P2/A2: deduced T = double
              // error: deduction fails, T is ambiguous
good(x, 1.2); // P1 = std::vector<T>, A1 = std::vector<std::complex<double>>
              // P1/A1: deduced T = std::complex<double>
              // P2 = identity<T>::type, A2 = double
              // P2/A2: uses T deduced by P1/A1 because T is to the left of :: in P2
              // OK: T = std::complex<double>

... дедукция typename Char не происходит, т.к. он вложен в String и зависит от определеня String. Однако я еще не до конца не понимаю, почему параметр по умолчанию игнорируется (возможно из-за того, что была проба дедукции?).