【问题标题】:C++ - deduce parameter pack (variadic template) constructor and copy constructor by enable_if_tC++ - 通过 enable_if_t 推导出参数包(可变参数模板)构造函数和复制构造函数
【发布时间】:2016-03-26 05:04:01
【问题描述】:

更新:
谢谢你,Jamboree。
这是最后的struct A

struct A
{
    template<class ... Args,class=std::enable_if_t<(sizeof...(Args)!=1)>>
    A(Args &&...args)
    {
        cout<<'v';
    }
    template<class Arg,class=std::enable_if_t<!std::is_base_of<std::remove_reference_t<Arg>,A>::value>>
    A(Arg &&arg)
    {
        cout<<'v';
    }
    A(const A &)
    {
        cout<<'c';
    }
    A(A &&)
    {
        cout<<'m';
    }
};

产地:
关于这段代码,

#include<iostream>
#include<type_traits>
#include<utility>
using namespace std;

struct A
{
    template<class ... Args,class=std::enable_if_t<
        sizeof...(Args)!=1
        ||!std::is_same<std::remove_cv_t<std::remove_reference_t<Args>>,A>::value>>
    A(Args &&...args)
    {
        cout<<'v';
    }
    A(const A &)
    {
        cout<<'c';
    }
    A(A &&)
    {
        cout<<'m';
    }
};

int main()
{
    A a{10};
    A b{10,20};
    A c{b};
    const A d{c};
    A e{move(c)};
}

在 VC++ 14.0 中输出为vvvvm
但是为什么输出不是vvccm
(我希望c and d 使用复制构造函数。而且我知道 Effective Modern C++ Item 27 只使用一个转发引用。)

【问题讨论】:

  • 使用Args unexpanded 应该是格式错误的。
  • 但是如果我使用std::remove_reference_t&lt;Args...&gt;,就会出现编译错误。

标签: c++ templates c++14 sfinae variadic


【解决方案1】:

因为bc,当您将它们传递给cd 的ctor 时,它们是A&amp; 给编译器(不是常量限定),因此Args &amp;&amp;...argsconst A &amp;.

要实现你想要的,你可以这样做:

struct A
{
    A() = default;

    template<class ... Args,std::enable_if_t<(sizeof...(Args)>1), bool> = true>
    A(Args &&...args)
    {
        cout<<'v';
    }

    template<class Arg,std::enable_if_t<!std::is_base_of<A, std::remove_reference_t<Arg>>::value, bool> = true>
    A(Arg && arg)
    {
        cout<<'v';
    }

    A(const A &)
    {
        cout<<'c';
    }
    A(A &&)
    {
        cout<<'m';
    }
};

【讨论】:

  • 在这个例子中,总是需要一个默认的构造函数。如果没有明确指定,请确保改为 sizeof...(Args)!=1
猜你喜欢
  • 2016-01-02
  • 1970-01-01
  • 2016-09-02
  • 2012-06-17
  • 2011-10-21
  • 1970-01-01
  • 2014-01-29
  • 2018-05-18
  • 2015-11-24
相关资源
最近更新 更多