pair的两个构造函数几乎相同,为什么不生成构建错误?

the two constructors of pair is almost the same, why not generate build error?

本文关键字:为什么不 错误 构建 构造函数 两个 pair      更新时间:2023-10-16

在pair的实现中,接下来的两个构造函数仅在前缀上有所不同:显式。 两个成员模板函数几乎相同。

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

那么为什么结果不同呢?

下面的类不使用上面的模板。

此错误是由您两次描述同一构造函数的事实引起的。

explicit只是限制构造函数的调用方式,而不是允许重载的签名更改。

区别不仅在于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本身不会影响重载解析,它只是意味着构造函数只能在直接初始化上下文中使用。