class A
{
public:
using number_t = std::int32_t;
using string_t = std::string;
template < class T >
using vector_t = std::vector < T >;
public:
template < class T1, class T2, class T3 >
A(T1 && n, T2 && s, T3 && v) :
m_n { std::forward < T1 > (n) },
m_s { std::forward < T2 > (s) },
m_v { std::forward < T3 > (v) } {}
private:
number_t m_n;
string_t m_s;
vector_t < number_t > m_v;
};
Вопрос: нужно ли проверять типы T1, T2, T3 в конструкторе? Я так полагаю, что нужно, потому что этот конструктор запросто съедает, например, в качестве первого аргумента double, что нежелательно. Как корректно сделать проверку? Рассматриваю вариант std::enable_if_t и std::is_same. Если так, то как удалять ссылки в случае приема конструктором lvalue-значения? Компилятор ругается на std::is_same < number_t, std::remove_reference< T1 >::type >::value. Пишет: «ожидался тип, а не вот это».
Ответ
Мне кажется, что в данном случае логично применить std::decay - типа
template
Кстати говоря,
typename = enable_if_t
тоже вполне работает. Причем в определенных ситуациях даже лучше - например, const int decay пропустит, убрав const, а вот remove_reference_t - уже нет, так что если, например, конструктор требует именно ссылку, а не константную ссылку - лучше remove_reference_t, если константную ссылку - лучше decay.
Словом, подгонять по месту с помощью напильника и какой-то матери... :)
Комментариев нет:
Отправить комментарий