gpt4 book ai didi

c++ - 如何使用 C++11 风格的强类型定义创建新的原始类型?

转载 作者:IT老高 更新时间:2023-10-28 22:11:13 25 4
gpt4 key购买 nike

我正在尝试在 C++ 中模拟 distincttype来自 Nimprogramming language .下面的例子不会在 Nim 中编译,因为编译器会捕获变量 ed尽管有不同的类型(Error: type mismatch: got (Euros, float))两者都是二进制级别的 float :

type
Euros = distinct float

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

在 C++ 中实现此目的的一种方法是为 float 编写一个包装类。 <罢工>但是这不适用于导出类型的 API,因为大小不会与 float 相同。或者即使一个类的大小与一个类的存储长度相匹配float,它永远不会匹配 char 类型的大小。 如果您还实现了所有可能的操作符,如加法、减法等,这将起作用,但需要大量输入和重复代码。

较早的问题,例如 Creating a new primitivetype已接受使用 boost 的强 typedef 的答案。然而 typedef似乎只适用于函数类型签名,typedef 不会阻止两个要添加在一起的浮点继承类型并且它们的类型完全改变(嗯,因为只是一种新类型的错觉):

#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,所以我找了这个新支持,发现Bjarne Stroustrup himself gave a C++11 stylekeynote in2012 .大约在第 21 分钟,他开始谈论这些新的强类型定义。如果你只下载幻灯片,第 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;
}

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

$ 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 试图展示的完整示例吗?

最佳答案

C++11 中没有强类型定义。支持 <chrono> 的单位但那是完全不同的事情。没有人能就强类型定义应该有什么行为达成一致,确切地说,所以从来没有对它们提出任何建议,所以它们不仅不在 C++11 也不在 C++14 中,在这方面没有现实的前景他们进入任何 future 标准的时间。

关于c++ - 如何使用 C++11 风格的强类型定义创建新的原始类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23726038/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com