我想向用户隐藏库实现,并为公共API提供实现的别名,以减少代码重复。因此,如果我有两个逻辑上不同的API结构,但它们的实现是相等的,则实现将被别名,如代码片段所示。
// library implementation
namespace impl {
struct A {};
}
// library public API
using A1 = impl::A;
using A2 = impl::A;
// library usage
int main(int argc, char* argv[]) {
using type = A1;
// do some stuff
using type = A2; // prevent this redefinition with reporting warning or error
// do some more stuff
return 0;
}
但是,如果用户决定像代码片段中那样将别名重新定义为库公共API,则可能会导致隐藏的逻辑错误,因为它编译得很好。所以问题是:
如果将重新定义的别名引用到相同类型,是否可以防止别名到别名的重新定义?
答案 0 :(得分:0)
如果您指向相同的类型,则编译器对此完全没有问题,恐怕您对此无能为力。
在您的情况下,从typedef
关键字基本上等同于using
关键字:
https://en.cppreference.com/w/cpp/language/typedef
Typedef不能用于更改现有类型名称的含义 (包括typedef名称)。声明后,typedef名称只能是 重新声明再次引用相同的类型。
因此,使用不同的 type-id 重新声明typedef名称是错误的。重新声明具有相同 type-id 的typedef名称没有任何作用。
答案 1 :(得分:0)
最简单的解决方法可能是继承:
struct A1 : public impl::A
{
using A::A;
};
struct A2 : public impl::A
{
using A::A;
};
这定义了新类型,但是重用了实现。您甚至可以使用私有继承,但这将需要其他成员using
进行更多声明。