您可能知道typedef更像是C ++中的别名而不是新类型,详情可以在这里看到:
http://dlang.org/cpptod.html#typedefs
我真的不喜欢链接中提出的解决方案,所以我想知道有更好的方法吗?
答案 0 :(得分:7)
只有一种方法可以在C ++中引入新类型 - 带有类关键字(union
/ struct
/ class
/ enum
...)。有一些方法可以隐藏宏后面的这些东西,并使这些新类型与旧版本一样直观可用(参见BOOST_STRONG_TYPEDEF
),但事实仍然是它是引入这种新类型的唯一方法。 / p>
想象一下,你有一个newtype
关键字,它构成了一个强大的typedef:
newtype foo = int; // with 'using' alias syntax
该类型的转化如何运作?如果没有转换,您永远不能为新类型的对象分配任何值。只有显式转换可能看起来很直观,但是如果真的想要隐式转换,并且仍能够重载怎么办?好吧,运气不好。您可以添加各种语法以将决定留给用户,但我确信您始终可以提出需要新语法的极端情况。只需将其设为struct
,将其隐藏在宏后面即可完成。
答案 1 :(得分:2)
通用“没时间制作正确的界面”宏:
#define STRONG_CLASS_TYPEDEF(oldType, newType) \
struct newType : private oldType { \
template<typename... T> \
newType(T... foo) : oldType(foo...) {} \
oldType* operator->() { return this; } \
oldType& operator*() {return *this;} \
};
如果编译器不支持可变参数模板,则需要手动插入所需的构造函数。这基本上是一个构建你自己的继承构造函数。
不幸的是,我认为不可能将新类型限制为隐式转换为基类,而是公开其所有公共字段。有一些解决方法:
您只需using oldType::X;
所需的所有方法和变量即可。这绝对是最好的解决方案,但需要一段时间才能完成。
或者使用偷偷摸摸的箭头操作符重载并调用foo->method();
。或者“取消引用”新的强类型到基类型。这些基本上只是一个花哨的显式演员。但是考虑operator oldType()
(显式与否)甚至不能用于私有继承......
无论如何,这是std::string
和Name
示例的强类型。
struct Name : private std::string {
template<typename... T>
Name(T... foo) : std::string(foo...) {}
std::string* operator->() { return this; }
const std::string& operator*() {return *this;}
//The above is obviously a bad idea if you want to use this alongside pointers
using std::string::resize;
using std::string::size;
using std::string::insert;
using std::string::operator[];
// etc.
//Simplest to use, but a bit more to set up
};
此外,您必须在此示例中包装非成员运算符重载(std :: string ==
)。
bool operator==(Name& lhs, Name& rhs) { return *lhs == *rhs; }
//Note: "Dereference" turns it into a std::string, as above
公平警告,除了基本机制之外,我没有进行太多测试。它可能会增加(非常)少量的开销。但是有效的空类是可能已经优化了。
答案 2 :(得分:1)
使用BOOST_STRONG_TYPEDEF
在C ++中创建“strongdefs”。没有内置语言功能。
那说知道你试图解决的真正问题会很有趣,因为我发现非别名typedef
在我所使用的代码中非常小。< / p>
答案 3 :(得分:0)
C ++中的新类型只能以某种方式聚合子类型。但由于函数重载基于静态类型,因此必须重新声明所有操作和函数。
C ++ typedef
就像D alias
es。
如果起始类型是一个类或结构,继承可以以某种方式帮助(至少操作仍然可以像旧参数一样工作)但是一切都是关于返回类型的,必须正确地重新定义转换,否则一切都会无差别地上下转换从而消除了新型的优势。
答案 4 :(得分:0)
C ++中有很多方法可以执行类型检查。 考虑以下代码,基本思想与链接中给出的示例相同,但我认为它更直接:
struct Handle2 {void * ptr;} ;
void bar(Handle2) {}
void foo(void *) {}
int main() {
Handle2 h2 = {(void*)-1};
foo(h2); //! won't pass through compiling
bar(h2);
}