Как неявно приводить аргументы шаблонного конструктора?
Я перегружаю конструктор шаблонного класса A
с разными типами ввода для аргументов скалярного и контейнерного типа:
template<typename T>
class A {
public:
A();
A(T&& _val) { printf("non-template constructor\n");} ;
template<typename iT> A(const iT& _cont) { printf("template constructor\n");};
};
int main(int argc, char const *argv[]) {
A<float> foo1(0.9); //template constructor
A<float> foo2((float)0.9); //no-template constructor
A<float> foo3(std::vector<int>(5,8)); //template constructor
return 0;
}
Тем не менее, есть ли способ вызвать принудительно не шаблонный конструктор для неявно приводимых типов, например, передавая double
конструктор A<float>()
?
1 ответ
Решение
Да, вы можете добавить SFINAE-ограничение в шаблон конструктора:
template<typename iT,
std::enable_if_t<!std::is_convertible_v<iT&&, T>>* = nullptr>
A(const iT&) { printf("template constructor\n"); }
Это приводит к сбою замены для выведенного типа iT
когда iT&&
конвертируется в T
, который удаляет шаблон конструктора из набора перегрузки.
(Вам нужно #include <type_traits>
для различных библиотечных средств, используемых для выражения ограничения.)