Ответ 1
В Dev Studio следующие ошибки:
#include "stdafx.h"
#include <vector>
#include <iostream>
template <typename T>
std::vector<std::vector<T> > transform(std::vector<std::vector<T> > const &vec,
std::vector<std::vector<std::vector<std::vector<T> > > > const &m,
T z = T(0), T w = T(1));
template <typename T>
std::vector<std::vector<T> > transform(std::vector<std::vector<T> > const &vec,
std::vector<std::vector<std::vector<std::vector<T> > > > const &m,
T z, T w)
{
std::cout << "Z" << z << "\n";
std::cout << "W" << w << "\n";
return vec;
}
int _tmain(int argc, _TCHAR* argv[])
{
std::vector<std::vector<int> > xi;
std::vector<std::vector<std::vector<std::vector<int> > > > mi;
transform(xi,mi);
std::vector<std::vector<float> > xf;
std::vector<std::vector<std::vector<std::vector<float> > > > mf;
transform(xf,mf);
std::vector<std::vector<double> > xd;
std::vector<std::vector<std::vector<std::vector<double> > > > md;
transform(xd,md);
}
Вывод:
Z0
W1
Z0
W1.4013e-045
Z2.122e-314
W3.60689e-305
Поэтому я полагаю, что это не работает, как ожидалось!!!
Если вы удалите предварительную декларацию и поместите аргументы по умолчанию в функцию шаблона, то она будет работать как ожидалось.
#include "stdafx.h"
#include <vector>
#include <iostream>
template <typename T>
std::vector<std::vector<T> > transform(std::vector<std::vector<T> > const &vec,
std::vector<std::vector<std::vector<std::vector<T> > > > const &m
T z = T(0), T w = T(1))
{
std::cout << "Z" << z << "\n";
std::cout << "W" << w << "\n";
return vec;
}
int _tmain(int argc, _TCHAR* argv[])
{
std::vector<std::vector<int> > xi;
std::vector<std::vector<std::vector<std::vector<int> > > > mi;
transform(xi,mi);
std::vector<std::vector<float> > xf;
std::vector<std::vector<std::vector<std::vector<float> > > > mf;
transform(xf,mf);
std::vector<std::vector<double> > xd;
std::vector<std::vector<std::vector<std::vector<double> > > > md;
transform(xd,md);
}
Это работает так, как ожидалось.
Это связано с тем, что предварительная декларация шаблона не является предварительным объявлением функции и, следовательно, на самом деле не имеет параметров по умолчанию, и поэтому вы получаете случайные значения в списке параметров.
OK. Не из моего чтения стандарта это должно работать как ожидалось:
Использование n2521
Раздел 14.7.1 Неявная реализация
Пункт 9
Реализация не должна имплицитно создавать шаблон функции, шаблон-член, не виртуальную функцию-член, класс-член или статический элемент данных шаблона класса, который не требует создания экземпляра. Неясно, реализует ли реализация неявно экземпляр виртуальной функции-члена шаблона класса, если бы функция виртуального члена не была бы реализована иначе. Использование специализации шаблона в аргументе по умолчанию не должно приводить к тому, что шаблон неявно создается, за исключением того, что шаблон шаблона может быть создан, когда его полный тип необходим для определения правильности аргумента по умолчанию. Использование аргумента по умолчанию в вызове функции приводит к тому, что специализации в аргументе по умолчанию неявно создаются.
Полужирная часть параграфа кажется мне (мне), чтобы указать, что каждая специализация, созданная из-за аргументов по умолчанию, будет неявно создаваться в блоке перевода при использовании.
Пункт 11:
Если шаблон функции f вызывается таким образом, что требуется использовать выражение аргументов по умолчанию, зависимые имена просматриваются, проверяются ограничения семантики и выполняется создание экземпляра любого шаблона, используемого в выражении аргумента по умолчанию как будто выражение аргумента по умолчанию было выражением, используемым в специализации шаблона функции с той же областью, теми же параметрами шаблона и тем же доступом, что и шаблон функции f, используемый в этой точке. Этот анализ называется созданием аргументов по умолчанию. Конкретный аргумент по умолчанию затем используется как аргумент f.
Указывает, что даже если аргументы по умолчанию являются параметрами шаблона, они будут правильно созданы.
Надеюсь, я правильно это понял.: -)