2

Я хочу реализовать идеальный конструктор переадресации в моем классе «myArgs», , который должен участвовать только в специализациях myClassBase<>. Грубо говоря: вызвать этот конструктор для каждого изменения myClassBase<>Шаблоны Variadic и совершенная пересылка в определенный класс шаблона

Но это не компилируется: '<function-style-cast>' : cannot convert from 'myClass' to 'myArgs'.

Я думаю, это потому, что компилятор не может вывести из Args&& в myClassBase<T, D>.

Смотреть это (очень простой) пример:

template <class T, class D> 
class myClassBase 
{ 
private: 
    T data; 
    D data2; 
}; 

typedef myClassBase<char, int> myClass; 

class myArgs 
{ 
public: 
    myClass m_data; 

    template <class T, class D> 
    myArgs(myClassBase<T, D>&& rhs) : 
     m_data(std::forward< myClassBase<T, D> >(rhs)) 
    { 
    } 
}; 

template <class... Args> 
void var_args(Args&&... args) 
{ 
    myArgs(std::forward<Args>(args)...); 
} 

испытания материал:

myClass x; 

var_args(x); 

Если я изменить параметр функции var_args из void var_args(Args&&... args) в void var_args(Args... args) он работает.

КПП. в моем реальном коде myClass, конечно, поддерживает семантику переноса.

Заранее спасибо. Кристиан.

ответ

1
template <class T, class D> 
myArgs(myClassBase<T, D>&& rhs) : 
    m_data(std::forward< myClassBase<T, D> >(rhs)) 
{ 
} 

rhs есть ссылка Rvalue, а не ссылка переадресации. Ссылка на пересылку в функциональном параметре имеет вид T&&, где T - некоторый вычисленный параметр шаблона. Вы можете исправить это, выведя T, а не указав myClassBase.

template <class T> 
myArgs(T&& rhs) : 
    m_data(std::forward<T>(rhs)) 
{ 
} 

Если вы хотите, чтобы эта функция действительна только если T является myClassBase, вы можете написать черту, чтобы проверить это:

template <typename T> 
struct isMyClassBaseImpl : std::false_type{}; 

template <typename T, typename D> 
struct isMyClassBaseImpl<myClassBase<T,D>> : std::true_type{}; 

template <typename T> 
using isMyClassBase = isMyClassBaseImpl<std::decay_t<T>>; 

Тогда вы можете SFINAE его:

template <class T, std::enable_if_t<isMyClassBase<T>::value>* = nullptr> 
myArgs(T&& rhs) : 
    m_data(std::forward<T>(rhs)) 
{ 
}