【发布时间】:2016-11-30 12:16:39
【问题描述】:
更新:有人提议在某些情况下更改auto 的含义。
Implicit Evaluation of “auto” Variables and Arguments 由 Joel Falcou 和其他人撰写。
隐式评估应:
- 使类实现者能够指示此类的对象在 auto 语句中进行评估;
- 使他们能够确定评估对象的类型;
...
C++11 的 auto 关键字很棒。
但是在我看来,如果一个类型是Not Regular(例如,参见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> 的问题,但它会使错误的使用更加困难。
我错过了什么吗?我应该改变设计的其他部分吗?非常规类是否应具有有助于编译器确定更通用自动的类型特征(例如,将 bool 推导出为 auto b = v[10] 其中 std::vector<bool> v。)
【问题讨论】:
-
是否添加了
static_assert来分配可能性? -
@wasthishelpful,赋值不是问题,我可以在
operator=中实现我需要的语义,甚至可以删除。问题是允许这种auto r = rd语法,并允许它具有错误的含义(在 C++ 中似乎不可能更改)。auto r = rd这行不是赋值,而是带有(错误的)类型推导的构造。 (更具体地说,对于“类引用类型”,它是(或应该是)绑定操作)。 -
根据cplusplus.com/reference/functional/reference_wrapper,您可以通过调用
ref.get()访问您的值。从中构建应该是明确的。 -
是的,如果 C++ 有一些特性可以避免在涉及类型时让你自爆,那不是很好吗?但是,如果我们愿意,在我的列表中禁用有符号和无符号类型之间的隐式转换的能力会更高......
-
不,无法禁用此核心语言功能。直到有人编写了一个连贯的提案并完成了将其合并到下一个 C++ 标准中所需的所有工作。
auto被定义为做一件非常具体的事情,而这件事情和模板参数推导中发生的事情完全一样。如果您建议在某些情况下禁用auto,您可能还应该在相同情况下禁用模板参数推导,以保持一致性。
标签: c++ c++11 auto regular-type