11

this answer之后,似乎这些构造函数:

template<class U, class V> pair(pair<U, V>&& p); 
template<class U, class V> pair(const pair<U, V>& p);

当它们需要显式转换时,它们被禁止参与重载决议。

从 C++11(§20.3.2,n3290)开始:

备注:此构造函数不应参与重载决议,除非 U 可隐式转换为 first_type 并且 V 可隐式转换为 second_type。

有人提出了一个有趣的SFINAE 解决方法,但这偏离了标准的文本。

如果没有一些特殊的内部编译器魔法,一个符合要求的实现怎么可能将其排除在重载决议之外?即一个实现可以做到这一点,我可以为我自己的类型复制它吗?似乎没有任何符合这一点的方法!这是从 C++11 中删除概念的后遗症吗?

我确实想知道使用私有构造函数来执行 SFINAE 部分并从公共构造函数委托,但它看起来不像构造函数委托以某种方式参与 SFINAE 以使其工作。

4

2 回答 2

4

但这偏离了标准的文本

允许实现向任何非虚拟库成员函数添加默认参数。这似乎恰好允许这种 SFINAE 技巧。

于 2011-11-15T16:00:34.463 回答
1

我错过了两条信息:

  1. gcc 使用这个:

    template<class _U1, class _U2, class = typename
                   std::enable_if<std::is_convertible<_U1, _T1>::value
                                  && std::is_convertible<_U2, _T2>::value>::type>
            pair(_U1&& __x, _U2&& __y)
            : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { }
    

    诀窍似乎是匿名class模板参数的默认值。我以前没见过,这个实现没有使用它。

  2. 我错过了 gcc 实际上实现了这一点。
于 2011-11-15T16:00:57.827 回答