Явное задание шаблонного параметра конструктора
Допустим, есть класс с конструктором. У конструктора есть шаблонный параметр:
template<typename T> class A {
T v;
public:
template<typename U> A(T p,U u) : v(p)
{
std::cout << u << v << std::endl;
}
};
Тип U может быть выведен:
int main()
{
A<int> b(2,'A'); // Ok, U = char
auto x = A<int>::A(1,'A'); // Ok, U = char
}
А можно ли задать его явно, не через аргумент конструктора? Как-то так:
int main()
{
A<int,char> b(2,'A'); // не работает
A<int><char> b(2,'A'); // не работает
auto y= A<int>::A<char>(2, 'A'); // не работает
}
Ответы (3 шт):
В таком виде - нет. Но можно, если измените сигнатуру шаблона.
Сделайте параметр шаблона конструктора параметром шаблона всего класса.
template<typename T, typename U>
class A
{
T v;
public:
A(T p,U u) : v(p)
{
std::cout << u << v << std::endl;
}
};
int main()
{
A<int,char> b(2,'A'); // работает
A c(3,'A'); // автовыведение типа
}
У конструкторов нельзя выбирать, а простых методов можно. Просто укоротите конструктор функционально и вызовите шаблонный метод.
#include <iostream>
template<typename T>
class A {
T v;
public:
A(T p) : v(p) { }
template<typename U>
A & Constructor(U u){
std::cout << u <<' '<< v << std::endl;
return * this ;
}
} ;
int main (){
A<int>(1).Constructor<double>(3);
A<int> a(2) ;
a.Constructor<char>('4');
}
Это просто принцип. А теперь красота:
Для красоты можете создать шаблонный класс только для конструкторов :
#include <iostream>
template<typename T>
class A {
T v;
protected :
A(T p) : v(p) { }
template<typename U>
A & Constructor(U u){
std::cout << u <<' '<< v << std::endl;
return * this ;
}
} ;
template<typename T,typename U>
class B : public A<T> {
public:
B ( T v , U u ) : A<T> ( v ) {
A<T>::Constructor(u);
}
} ;
int main (){
B<char,double> b ( '1' , 2.5 ) ;
A<char> & a = b ;
}
Объект B включает в себя класс A и он будет работать точно так-же как и класс A. Вызов внутренних шаблонных методов будет спрятан от глаз пользователя.
В продолжение идеи AlexGlebe. Так нельзя забыть вызвать Constructor:
#include <iostream>
template<typename T>
class A {
T v;
A(T p) : v(p) { } //Приватный конструктор
public:
template<typename U>
static A constructor(T p, U u){
A out(p);
//Constructor
std::cout << u <<' '<< out.v << std::endl;
return out;
}
};
int main (){
A<int> a = A<int>::constructor<char>(2,'A');
return 0;
}