Почему аргументы шаблона по умолчанию только позволяются на шаблонах классов? Почему мы не можем определить тип по умолчанию в шаблоне функции членства? Например:
struct mycclass {
template<class T=int>
void mymember(T* vec) {
// ...
}
};
Вместо этого силы C++, которые аргументы шаблона по умолчанию только разрешены на шаблоне класса.
Имеет смысл указать аргументы шаблона по умолчанию. Например, вы можете создать функцию сортировки:
template<typename Iterator,
typename Comp = std::less<
typename std::iterator_traits<Iterator>::value_type> >
void sort(Iterator beg, Iterator end, Comp c = Comp()) {
...
}
C ++ 0x знакомит их с C ++. См. Этот отчет о дефектах, сделанный Бьярном Страуструпом: Аргументы шаблона по умолчанию для шаблонов функций и то, что он говорит
Запрещение аргументов шаблона по умолчанию для шаблонов функций - это забытый пережиток времени, когда автономные функции рассматривались как вторые граждане класса и требовал, чтобы все аргументы шаблона выводились из аргументов функции, а не указывались.
Ограничение серьезно затрудняет стиль программирования, из-за того, что автономные функции излишне отличаются от функций-членов, что затрудняет написание кода в стиле STL.
Процитировать Шаблоны C ++: Полное руководство (стр. 207):
Когда шаблоны были изначально добавлены в язык C ++, явные аргументы шаблона функции были недопустимая конструкция. Аргументы шаблона функции всегда должны выводиться из выражения вызова. В результате, казалось, не было веских причин для разрешения аргументов шаблона функции по умолчанию, потому что значение по умолчанию всегда переопределялось выведенным значением.
Пока что все предложенные примеры параметров шаблона по умолчанию для шаблонов функций могут быть выполнены с перегрузками.
AraK:
struct S {
template <class R = int> R get_me_R() { return R(); }
};
может быть:
struct S {
template <class R> R get_me_R() { return R(); }
int get_me_R() { return int(); }
};
Моим:
template <int N = 1> int &increment(int &i) { i += N; return i; }
может быть:
template <int N> int &increment(int &i) { i += N; return i; }
int &increment(int &i) { return increment<1>(i); }
litb:
template<typename Iterator, typename Comp = std::less<Iterator> >
void sort(Iterator beg, Iterator end, Comp c = Comp())
может быть:
template<typename Iterator>
void sort(Iterator beg, Iterator end, std::less<Iterator> c = std::less<Iterator>())
template<typename Iterator, typename Comp >
void sort(Iterator beg, Iterator end, Comp c = Comp())
Stroustrup:
template <class T, class U = double>
void f(T t = 0, U u = 0);
Может быть:
template <typename S, typename T> void f(S s = 0, T t = 0);
template <typename S> void f(S s = 0, double t = 0);
Который я доказано с помощью следующего кода:
#include <iostream>
#include <string>
#include <sstream>
#include <ctype.h>
template <typename T> T prettify(T t) { return t; }
std::string prettify(char c) {
std::stringstream ss;
if (isprint((unsigned char)c)) {
ss << "'" << c << "'";
} else {
ss << (int)c;
}
return ss.str();
}
template <typename S, typename T> void g(S s, T t){
std::cout << "f<" << typeid(S).name() << "," << typeid(T).name()
<< ">(" << s << "," << prettify(t) << ")\n";
}
template <typename S, typename T> void f(S s = 0, T t = 0){
g<S,T>(s,t);
}
template <typename S> void f(S s = 0, double t = 0) {
g<S,double>(s, t);
}
int main() {
f(1, 'c'); // f<int,char>(1,'c')
f(1); // f<int,double>(1,0)
// f(); // error: T cannot be deduced
f<int>(); // f<int,double>(0,0)
f<int,char>(); // f<int,char>(0,0)
}
Печатный вывод соответствует комментариям для каждого вызова f, а закомментированный вызов не может быть скомпилирован должным образом.
Поэтому я подозреваю, что параметры шаблона по умолчанию «не нужны», но, вероятно, только в том же смысле, что и аргументы функции по умолчанию «не нужны». Как указывает отчет Страуструпа о дефектах, добавление невыведенных параметров было слишком поздно, чтобы кто-либо осознал и / или по-настоящему оценил, что это сделало значения по умолчанию полезными. Таким образом, текущая ситуация основана на версии шаблонов функций, которая никогда не была стандартной.