如何使用C 11风格的强大的typedef创建一个新的基本类型?

栏目: C++ · 发布时间: 6年前

内容简介:在Nim中编译,因为编译器捕获变量e和d有不同的类型(错误:类型不匹配:got(欧元,浮动))尽管两者都是二进制的浮点数:
我试图在

Nim

的C a

distinct

中效仿.以下示例不会

在Nim中编译,因为编译器捕获变量e和d

有不同的类型(错误:类型不匹配:got(欧元,浮动))尽管

两者都是二进制的浮点数:

type
  Euros = distinct float

when isMainModule:
  var
    e = Euros(12.34)
    d = 23.3
  echo (e + d)

在C中执行此操作的一种方法是为浮动类编写一个包装类.但

这对于导出类型的API不起作用,因为大小不会

与浮动一样.或者即使类的大小与a的存储长度相匹配

float,它将永远不会匹配char类型的大小.如果您还实现了所有可能的操作符,例如加法,减法等操作,但是需要很多键入和复制代码,这将会起作用.

较旧的问题,如

Creating a new primitive

有一个接受的答案,使用boost的强大的typedef.但是typedef

似乎只适用于函数类型签名,typedef不会阻止两个

float-inherited类型要一起添加,其类型完全改变

(嗯,因为只有一种新型的错觉):

#include <boost/serialization/strong_typedef.hpp>
#include <stdio.h>

BOOST_STRONG_TYPEDEF(float, money);

void test(money a, float b)
{
    int t = a + b;
    printf("value is %d", t);
}

int main()
{
    money a(5.5);
    int euros(5);
    // This is not caught!
    int dollars = a + euros;
    printf("dollars %d\n", dollars);
    // But the compiler catches this misuse.
    test(euros, a);
}

但是几乎是这样,由于签名,test()调用将不起作用

不匹配,但语言仍然允许其他操作来处理类型

随意.

同样的答案提到C 0x带来强大的typedef,所以我寻找这个

大约二十一点,他开始谈论这些新的强大的typedefs.如果你

仅下载幻灯片,第19页开始谈论SI单位和更晚

第22和23页提到如何做到这一点.但是,我一直无法

使示例工作.这是我设法制作的拼凑:

template<int M, int K, int S> struct Unit { // a unit in the MKS system
    enum { m=M, kg=K, s=S };
};
template<typename Unit> // a magnitude with a unit
struct Value {
    double val; // the magnitude
    explicit Value(double d) : val(d) {} // construct a Value from a double
};

using Meter = Unit<1,0,0>; // unit: meter
using Second = Unit<0,0,1>; // unit: sec
using Speed = Value< Unit<1,0,-1> >; // meters/second type
constexpr Value<Second> operator "" _s(long double d)
// a f-p literal suffixed by ‘_s’
{
return Value<Second> (d);
}
constexpr Value<Meter> operator "" _m(long double d)
// a f-p literal suffixed by ‘_m’
{
return Value<Meter> (d);
}

int main(void)
{
    Speed sp1 = 100_m / 9.8_s;
    return 42;
}

我正在使用最新的Xcode 5.1.1使用命令行在MacOSX下进行编译:

$g++ unit.cpp -std=c++11
unit.cpp:13:25: error: constexpr function's return type 'Value<Second>' is not a
      literal type
constexpr Value<Second> operator "" _s(long double d)
                        ^
unit.cpp:5:8: note: 'Value<Unit<0, 0, 1> >' is not literal because it is not an
      aggregate and has no constexpr constructors other than copy or move
      constructors
struct Value {
       ^
unit.cpp:18:24: error: constexpr function's return type 'Value<Meter>' is not a
      literal type
constexpr Value<Meter> operator "" _m(long double d)
                       ^
unit.cpp:5:8: note: 'Value<Unit<1, 0, 0> >' is not literal because it is not an
      aggregate and has no constexpr constructors other than copy or move
      constructors
struct Value {
       ^
unit.cpp:26:20: error: no matching literal operator for call to 'operator "" _m'
      with argument of type 'unsigned long long' or 'const char *', and no
      matching literal operator template
    Speed sp1 = 100_m / 9.8_s;
                   ^
unit.cpp:26:28: error: no matching literal operator for call to 'operator "" _s'
      with argument of type 'long double' or 'const char *', and no matching
      literal operator template
    Speed sp1 = 100_m / 9.8_s;
                           ^
4 errors generated.

也许幻灯片中给出的例子,我还缺少一些代码?有人有一个完整的例子,Bjarne试图展示吗?


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

XML完全探索

XML完全探索

Steven Holzner / 中国青年出版社 / 2001-10 / 89.00

《XML完全探索》是完全根据读者的需要而设计的,书中有大量实际的XML场景。是一本尽可能深入地阐述XML的书籍,与其他XML书籍不同,本书中给出了上百个示例代码,完全测试通过,可供使用。 本书将帮助您:精通所有的从XML语法到XLink、从 XPointer到XML模式的XML标准;使用XSL和XSL格式化对象;使用XML和层叠样式表;利用Java和JavaScript,使用DOM解析器和一起来看看 《XML完全探索》 这本书的介绍吧!

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具