构造函数有条件标记为显式 [英] Constructor conditionally marked explicit

查看:98
本文介绍了构造函数有条件标记为显式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新条件显式 已纳入C ++ 20草案。 有关cppreference的更多信息

Update: conditional explicit has made it into the C++20 draft. more on cppreference

cppreference std :: tuple构造器页面具有许多C + +17注释表明诸如此类的内容:

The cppreference std::tuple constructor page has a bunch of C++17 notes saying things like:


此构造函数在以下情况下为 explicit std :: is_convertible< const Ti& ;, Ti> :: value 对于至少一个 i

This constructor is explicit if and only if std::is_convertible<const Ti&, Ti>::value is false for at least one i

如何编写有条件显式的构造函数?我想到的第一种可能性是 explicit(true),但这不是合法的语法。

How can one write a constructor that is conditionally explicit? The first possibility that came to mind was explicit(true) but that's not legal syntax.

尝试使用 enable_if 不成功:

// constructor is explicit if T is not integral
struct S {
  template <typename T,
            typename = typename std::enable_if<std::is_integral<T>::value>::type>
  S(T) {}

  template <typename T,
            typename = typename std::enable_if<!std::is_integral<T>::value>::type>
  explicit S(T) {}
};

,但出现错误:

error: ‘template<class T, class> S::S(T)’ cannot be overloaded
explicit S(T t) {}


推荐答案

添加了 N4387:改进对和元组,修订版3 给出了其工作方式示例:

The proposal that added that N4387: Improving pair and tuple, revision 3 has an example of how it works:


考虑下面的类模板A,该类模板打算将
用作其他某些类型T的包装:

Consider the following class template A that is intended to be used as a wrapper for some other type T:

#include <type_traits>
#include <utility>

template<class T>
struct A {
  template<class U,
    typename std::enable_if<
      std::is_constructible<T, U>::value &&
      std::is_convertible<U, T>::value
    , bool>::type = false
  >
  A(U&& u) : t(std::forward<U>(u)) {}

 template<class U,
    typename std::enable_if<
      std::is_constructible<T, U>::value &&
      !std::is_convertible<U, T>::value
    , bool>::type = false
  >
  explicit A(U&& u) : t(std::forward<U>(u)) {}

  T t;
};

所示的构造函数均使用完美转发,并且除了一个签名外,它们具有相同的签名。是明确的,其他
则不是。此外,它们相互排斥地受约束。
换句话说:此组合对于任何目标类型T
和任何参数类型U都起作用,例如单个构造函数,即
显式或非显式(或根本没有构造函数)。 / p>

The shown constructors both use perfect forwarding and they have essentially the same signatures except for one being explicit, the other one not. Furthermore, they are mutually exclusively constrained. In other words: This combination behaves for any destination type T and any argument type U like a single constructor that is either explicit or non-explicit (or no constructor at all).

正如Praetorian指出的,这正是 libstdc ++实现了

As Praetorian points out this is exactly how libstdc++ implements it.

如果我们相应地修改OP示例,它也可以工作:

If we modify the OPs example accordingly, it also works:

struct S {
  template <typename T,
            typename std::enable_if< std::is_integral<T>::value, bool>::type = false>
  S(T) {}

  template <typename T,
            typename std::enable_if<!std::is_integral<T>::value, bool>::type = false>
  explicit S(T) {}
};

这篇关于构造函数有条件标记为显式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆