C++ - 通过 enable_if_t 推导参数包(可变参数模板)构造函数和复制构造函数
C++ - deduce parameter pack (variadic template) constructor and copy constructor by enable_if_t
更新:
谢谢你,大露营。
这是最后的 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 只使用一个转发引用。)
因为 b
和 c
,当您将它们传递给 c
和 [=15] 的构造函数时,对于编译器(不是 const 限定的)是 A&
=], Args &&...args
因此比 const A &
.
更匹配
要实现你想要的,你可以这样做:
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';
}
};
更新:
谢谢你,大露营。
这是最后的 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 只使用一个转发引用。)
因为 b
和 c
,当您将它们传递给 c
和 [=15] 的构造函数时,对于编译器(不是 const 限定的)是 A&
=], Args &&...args
因此比 const A &
.
要实现你想要的,你可以这样做:
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';
}
};