有没有办法禁用非常规类型的自动声明? [英] Is there a way to disable auto declaration for non regular types?

查看:29
本文介绍了有没有办法禁用非常规类型的自动声明?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

UPDATE:建议在某些情况下更改 auto 的含义.

UPDATE: There is a proposal to change the meaning of auto in certain situations.

自动"变量和参数的隐式评估,作者:Joel Falcou 和其他人.

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

隐式评估应:

  1. 使类实现者能够在 auto 语句中指示对此类的对象求值;
  2. 使他们能够确定被评估对象的类型;

...

<小时>

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

但是在我看来,如果类型是不规则(例如,请参见 在移动语义的上下文中什么是常规类型"?)auto 的使用变得棘手.

However in my opinion if a type is Not Regular (see for example, What is a "Regular Type" in the context of move semantics?) the usage of auto becomes tricky.

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

Is there a way to disable the auto declaration for such type?

假设有一个模拟引用的 ref

Suppose one has a ref class that emulates a reference

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>`.

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

(in real life it would be a more complicated class, the important point is that the class at hand it is not regular.)

我发现 auto r = rd 不起作用(给出编译错误)的唯一方法是使类不可复制,但是我需要该类具有复制构造函数(具有特殊语义,但仍然是一个复制构造函数).

The only way I found auto r = rd not to work (give a compile error) is to make the class non copyable, however I need the class to have copy constructor (with a special semantics, but a copy constructor still).

有没有办法以某种方式禁用语法 auto r = rd ?当 decltype(rd) 不规则时.

Is there a way to disable a syntax auto r = rd somehow? when decltype(rd) is not regular.

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

(Even better could be to be able somehow to tell the compiler what auto should do precisely).

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

Note: This is not a very artificial problem, one could see that this type of problem is at the core of std::vector<bool>::reference (which is also a reference wrapper). Disabling (somehow) the syntax auto b = v[10] wouldn't solve the problem of std::vector<bool> but it will make bad usage harder.

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

Am I missing something? Should I change some other part of the design? Should the non-regular classes have a type trait that would help the compiler determine a more general auto (for example deduce bool for auto b = v[10] where std::vector<bool> v.)

推荐答案

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

A copy constructor means you expect the class to be copied. auto x = y; does a copy of y into x.

如果你想要一个不想自动运行的超级特殊副本,你可以使用代理对象.

If you want a super-special copy that you don't want to be run automatically, you can use a proxy object.

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永远不合法,因为没有任何东西有复制构造函数.

and now every attempt to copy strange must go through a call to pseudo, and use of auto is never legal, because nothing has a copy constructor.

您也可以将复制构造函数设为私有,并使用它来实现复制构造函数.

You could also make the copy constructor private, and use it to implement the pseudo copy constructor.

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

Note that the meaning of copy/move ctor is constrained by elision rules in C++.

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

In C++17 template class type deduction could make:

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.

这篇关于有没有办法禁用非常规类型的自动声明?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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