在对的实现中,接下来的两个构造函数的前缀不同:显式。两个成员模板的功能几乎相同。
template<class _Other1,
class _Other2,
enable_if_t<conjunction_v<
is_constructible<_Ty1, _Other1>,
is_constructible<_Ty2, _Other2>,
is_convertible<_Other1, _Ty1>,
is_convertible<_Other2, _Ty2>
>, int> = 0>
constexpr pair(_Other1&& _Val1, _Other2&& _Val2)
_NOEXCEPT_COND(is_nothrow_constructible_v<_Ty1, _Other1>
&& is_nothrow_constructible_v<_Ty2, _Other2>)
: first(_STD forward<_Other1>(_Val1)),
second(_STD forward<_Other2>(_Val2))
{ // construct from moved values
}
template<class _Other1,
class _Other2,
enable_if_t<conjunction_v<
is_constructible<_Ty1, _Other1>,
is_constructible<_Ty2, _Other2>,
negation<conjunction<
is_convertible<_Other1, _Ty1>,
is_convertible<_Other2, _Ty2>>>
>, int> = 0>
constexpr explicit pair(_Other1&& _Val1, _Other2&& _Val2)
_NOEXCEPT_COND(is_nothrow_constructible_v<_Ty1, _Other1>
&& is_nothrow_constructible_v<_Ty2, _Other2>)
: first(_STD forward<_Other1>(_Val1)),
second(_STD forward<_Other2>(_Val2))
{ // construct from moved values
}
但是当我编写如下的测试示例时:
class A
{
public:
template<typename T1,typename T2>
A(T1 a,T2 b){}
template<typename T1,typename T2>
explicit A(T1 a,T2 b){}
};
出现构建错误为:
Error C2535 'A::A(T1,T2)': member function already defined
那为什么结果不同?
答案 0 :(得分:2)
下面的类不使用上面的模板。
该错误是由于您两次描述相同的构造函数而引起的。
explicit
只是如何调用构造函数的一个限制,而不是允许过载的签名更改。
答案 1 :(得分:2)
区别不仅在于使用explicit
,而且enable_if_t
的模板参数也有不同的条件:
// Constructor 1 Constructor 2
enable_if_t<conjunction_v< enable_if_t<conjunction_v<
is_constructible<_Ty1, _Other1>, is_constructible<_Ty1, _Other1>,
is_constructible<_Ty2, _Other2>, is_constructible<_Ty2, _Other2>,
is_convertible<_Other1, _Ty1>, negation<conjunction<
is_convertible<_Other2, _Ty2> is_convertible<_Other1, _Ty1>,
is_convertible<_Other2, _Ty2>>>
如果所有四个条件都成立,则调用第一个构造函数(可以从_Ty1/2
构造_Other1/2
,并且可以将_Other1/2
转换为_Ty1/2
)。仅当后两个条件为假时,才调用第二个。
explicit
本身并不影响重载解析,仅表示构造函数只能在直接初始化上下文中使用。