如何使用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试图展示吗?


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

查看所有标签

猜你喜欢:

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

Cascading Style Sheets 2.0 Programmer's Reference

Cascading Style Sheets 2.0 Programmer's Reference

Eric A. Meyer / McGraw-Hill Osborne Media / 2001-03-20 / USD 19.99

The most authoritative quick reference available for CSS programmers. This handy resource gives you programming essentials at your fingertips, including all the new tags and features in CSS 2.0. You'l......一起来看看 《Cascading Style Sheets 2.0 Programmer's Reference》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

SHA 加密
SHA 加密

SHA 加密工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具