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

时间:2018-07-06 00:29:22

标签: c++ templates overloading

在对的实现中,接下来的两个构造函数的前缀不同:显式。两个成员模板的功能几乎相同。

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

那为什么结果不同?

2 个答案:

答案 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本身并不影响重载解析,仅表示构造函数只能在直接初始化上下文中使用。