禁用 typedef 之间的隐式转换 [英] Disable implicit conversion between typedefs

查看:25
本文介绍了禁用 typedef 之间的隐式转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 C++11 中,是否有一种干净的方法来禁用 typedef 之间的隐式转换,或者您是否必须做一些讨厌的事情,例如将您的 int 包装在一个类中并定义和删除各种运算符?

In C++11, is there a clean way to disable implicit conversion between typedefs, or do you have to do something nasty like wrap your int in a class and define and delete various operators?

typedef int Foo;
typedef int Bar;
Foo foo(1);
Bar bar(2);
bar = foo; // Implicit conversion!

推荐答案

C++ 标准说:

7.1.3 typedef 说明符

使用 typedef 说明符声明的名称将成为 typedef 名称.在其声明范围内,typedef-name 在语法上等同于关键字,并将与标识符关联的类型命名为第 8 条中描述的方式. typedef-name 因此是另一种类型的同义词.一个 typedef-name 做不要像类声明(9.1)或枚举声明那样引入新类型

A name declared with the typedef specifier becomes a typedef-name. Within the scope of its declaration, a typedef-name is syntactically equivalent to a keyword and names the type associated with the identifier in the way described in Clause 8. A typedef-name is thus a synonym for another type. A typedef-name does not introduce a new type the way a class declaration (9.1) or enum declaration does

但是例如classstruct 引入新的类型.在下面的例子中 uniqueUnused 实际上什么都不做,只是用来创建一个不同的类型 Value!= Value.所以也许这就是你正在寻找的东西.请记住,不能保证编译器摆脱外部结构!唯一保证此代码为您提供与 int 相同的大小

But e.g. class or struct introduce new types. In the following example uniqueUnused does actually nothing but is used to create a different type Value<int, 1> != Value<int, 2>. So maybe this is something you are looking for. Keep in mind there is no guarantee the compiler gets rid of the outer structure! The only guarantee this code gives you it's the same size as int

template<typename T, int uniqueUnused>
struct Value
{
  Value() : _val({}) {}
  Value(T val) : _val(val) { }
  T _val;
  operator T&() { return _val; }

  // evaluate if you with or without refs for assignments
  operator T() { return _val; }
};

using Foo = Value<int, 1>;
using Bar = Value<int, 2>;
static_assert(sizeof(Foo) == sizeof(int), "int must be of same size");
static_assert(sizeof(Bar) == sizeof(int), "int must be of same size");

如果你想基于类创建一个新类型,你可以简单地使用这个例子(这不适用于标量类型,因为你不能从整数继承):

If you want to create a new type based on a class you can simply go with this example (this doesn't work with scalar types since you can't inherit from ints):

class Foo : public Bar // introduces a new type called Foo
{
    using Bar::Bar;
};

这篇关于禁用 typedef 之间的隐式转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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