2

我想在我的“myArgs 类”中实现一个完美的转发构造函数,它应该只涉及myClassBase<>. 粗略地说:为每个变体调用此构造函数myClassBase<>

但它不会编译:'<function-style-cast>' : cannot convert from 'myClass' to 'myArgs'.

我认为这是因为编译器无法推断出Args&&to 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 当然支持移动语义。

提前致谢。基督教。

4

1 回答 1

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

rhs有一个右值引用,而不是转发引用。函数参数中的转发引用的形式T&&T一些推导的模板参数。您可以通过T推断而不是指定来解决此问题myClassBase

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

T如果您希望此函数仅在为 a时才有效myClassBase,您可以编写一个 trait 来检查它:

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))
{
}
于 2015-12-16T11:06:27.237 回答