gpt4 book ai didi

c++ - 有没有办法禁用非常规类型的自动声明?

转载 作者:可可西里 更新时间:2023-11-01 16:18:49 29 4
gpt4 key购买 nike

更新:有人建议更改 auto 的含义在某些情况下。

Implicit Evaluation of “auto” Variables and Arguments by Joel Falcou and others.

The implicit evaluation shall:

  1. Enable class implementers to indicate that objects of this class are evaluated in an auto statement;
  2. Enable them to determine the type of the evaluated object;

...


C++11 的 auto关键字很棒。

但是在我看来,如果类型不是常规(例如,参见 What is a "Regular Type" in the context of move semantics? ),则使用 auto变得棘手。

有没有办法禁用 auto这种类型的声明?

假设一个人有一个 ref模拟引用的类

double 5.;
ref<double> rd = d; // `ref` behaves like a reference, so it is not a regular type
ref<double> rd2 = rd; // `ref` can be (syntactically) copy constructible, (it is not regular for other reason)
auto r = rd; // now r is not `double`, but EVEN WORST it is `ref<double>`.

(在现实生活中它会是一个更复杂的类,重要的是手头的类不是规则的。)

我找到的唯一方法 auto r = rd不工作(给出编译错误)是使类不可复制,但是我需要类具有复制构造函数(具有特殊语义,但仍然是复制构造函数)。

有没有办法禁用语法 auto r = rd不知何故?什么时候decltype(rd)不规则。

(更好的办法是能够以某种方式告诉编译器 auto 应该做什么)。

注意:这不是一个非常人为的问题,可以看出这类问题是std::vector<bool>::reference的核心。 (这也是一个引用包装器)。禁用(以某种方式)语法 auto b = v[10]不会解决 std::vector<bool> 的问题但它会使糟糕的使用变得更加困难。

我错过了什么吗?我应该更改设计的其他部分吗?非常规类是否应该具有有助于编译器确定更通用的 auto 的类型特征(例如推导出 bool for auto b = v[10] where std::vector<bool> v .)

最佳答案

复制构造函数意味着您希望类被复制。 auto x = y;y 复制到 x 中。

如果你想要一个你不想自动运行的 super 特殊拷贝,你可以使用一个代理对象。

template <class T>
struct pseudo_copy;

template <class T>
struct pseudo_copy<T const&> {
T const& t;

// T const& can be initialized from T&&:
pseudo_copy(T const& tin) :t(tin) {}
pseudo_copy(T&& tin): t(tin) {}
pseudo_copy(pseudo_copy const&) = delete;
};

template <class T>
struct pseudo_copy<T&&> {
T&& t;
pseudo_copy(T&& tin): t(std::move(tin)) {}
pseudo_copy(pseudo_copy const&) = delete;
};

template <class T>
pseudo_copy<T const&> pseudo(T& t) { return {t}; }

template <class T>
pseudo_copy<T&&> pseudo(T&& t) { return {t}; }

struct strange {
strange(strange const&)=delete;
strange(pseudo_copy<strange const&>) {} // copy ctor
strange(pseudo_copy<strange&&>) {} // move ctor
strange() = default;
};

现在我们可以:

strange foo() { return pseudo(strange{}); }

strange x = pseudo(foo());

现在每次尝试复制strange 都必须调用pseudo,并使用auto永远是不合法的,因为没有复制构造函数。

您还可以将复制构造函数设为私有(private),并使用它来实现复制构造函数。


请注意,复制/移动构造函数的含义受 C++ 中省略规则的限制。


在 C++17 中,模板类类型推导可以:

template <class T>
struct value{
value_type_of<T> v;
value(T in): v(std::forward<T>(in)) {}
};

int x = 3;
value a = std::ref( x );

a.v 将是一个 int

关于c++ - 有没有办法禁用非常规类型的自动声明?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40888155/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com