你可能已经知道,在C++中,typedef更像是一个别名而不是新类型,详情可以参见这里:http://dlang.org/cpptod.html#typedefs
我真的不喜欢链接中提出的解决方案,所以我想知道是否有更好的方法?
你可能已经知道,在C++中,typedef更像是一个别名而不是新类型,详情可以参见这里:http://dlang.org/cpptod.html#typedefs
我真的不喜欢链接中提出的解决方案,所以我想知道是否有更好的方法?
union
/struct
/class
/enum
...)。有办法通过宏来隐藏这些内容,并使这些新类型像旧类型一样直观易用(参见BOOST_STRONG_TYPEDEF
),但事实仍然是,这是引入新类型的唯一方法。newtype
关键字,可以创建一个强类型定义:newtype foo = int; // with 'using' alias syntax
newtype foo = narrowing<int>
以及widening<>
、distinct<>
、explicit<>
和更多组合。其他编程语言实际上也具有这样的功能。 - Konrad Rudolphusing foo = narrowing<int, struct _foo_int_key>
呢?(这基本上就是 BOOST_STRONG_TYPEDEF
在幕后执行的操作)。由于这可以利用语言本身完成,所以我认为将其集成到核心语言中没有太大的必要。 - XeoBOOST_STRONG_TYPEDEF
真的只适用于内置类型吗?我忽略了那部分。让我编辑一下。 - Xeo通用的“没时间做一个合适接口”的宏:
#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
};
== )。
bool operator==(Name& lhs, Name& rhs) { return *lhs == *rhs; }
//Note: "Dereference" turns it into a std::string, as above
提醒一下,我没有测试过基本机制以外的内容。这可能会增加(非常)少量的开销。但是,这个几乎为空的类可能已经被优化掉了。
using
会破坏强类型定义的目的,因为它应该是简单的。你可以向基类添加公共引用,但是对于像operator==这样的函数,该怎么办呢? - BЈовићoperator==
的问题。是的,using
相当冗长。但它并没有违背其目的,因为它仍然不允许转换为基类。我不确定您所说的“对基类的公共引用”是什么意思。如果您指的是公共继承,则这违背了强typedef的目的,因为它允许隐式转换为基类。 - ECrownofFirestruct Name : private std::string { std::string& t; };
。 - BЈовић在C++中使用BOOST_STRONG_TYPEDEF
创建“strongdefs”。没有内置的语言功能可以实现这一点。
话虽如此,了解您尝试解决的真正问题会很有趣,因为我发现在我所涉及的代码中,需要非别名typedef
的情况非常少。
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);
}
C++中的新类型只能通过聚合子类型来实现。但由于函数重载是基于静态类型的,因此所有操作和函数都必须重新声明。
C++中的typedef
类似于D语言中的alias
。
如果起始类型是类或结构体,则继承可以在一定程度上帮助(至少操作仍然可以像旧参数一样工作),但一切都关乎返回类型和转换必须适当地重新定义,否则一切都会随意地向上和向下转换,从而消失了新类型的优势。