用于更简洁代码的嵌套命名空间



我目前正在编写一个适配器,用于在两个框架 A <-> B 之间转换类型。我对名字有点麻烦,因为在我看来,它们变得很长且不可读。然后我决定以一种非常嵌套的方式使用命名空间,我很少在其他任何地方看到。

老:

TypeA mylib::cvtToAtype(TypeB) {}
TypeB mylib::cvtToBtype(TypeA) {}

新增功能:

TypeA mylib::cvt::to_a::type(TypeB) {}
TypeB mylib::cvt::to_b::type(TypeA) {}

你会认为这是一种好的风格还是你看到严重的缺点?我认为它看起来很干净,但是如果有人决定"使用命名空间",它可能会被滥用。然后,类型并不是一个唯一名称来标识函数正在做什么。此外,名为"cvt"的命名空间也可能不是超级唯一的。

你觉得怎么样?

所以,你从:

TypeA mylib::cvtToAtype(TypeB) {}
TypeB mylib::cvtToBtype(TypeA) {}

您陈述的问题:函数名称"变得很长且不可读"。您建议:

mylib::cvt::to_a::type

首先,"cvt"不会被代码的读者/维护者无痛地识别为"转换"。 尾随::type对我来说似乎毫无意义。 任何称为"to_"的东西都可以预期是转换,所以我看不到::cvt::级别的意义。

无论它的价值如何,一些替代方案...

构造 函数

您可以考虑创建构造函数[explicit] TypeA::TypeA(TypeB)[explicit] TypeB::TypeB(TypeA),以便客户端用法很简单:

TypeA a{b};
functionThatWantsB(TypeB{a});

演员/转换模板

如果你想将函数与 TypeA/B 类分开,一个具有专用化的"强制"样式模板是一个不错的选择:

template <typename TypeTo, typename TypeFrom>
TypeTo convert(const TypeFrom&);
template <>
TypeB convert<TypeB, TypeA>(const TypeA& a) { return TypeB{...}; }
template <>
TypeA convert<TypeA, TypeB>(const TypeB& a) { return TypeA{...}; }

客户端用法是熟悉的强制转换符号:例如convert<TypeB>(a). 这比cvtToAtype强大得多,因为如果目标类型是抽象的 - 模板中的参数,来自usingtypedef的别名 - 您仍然可以强制转换。

知道目标类型,因为它是一个函数参数

另一种选择是具有转换为类型的函数参数,因此调用方不必将其键入为转换函数名称或模板参数的一部分:

TypeA& loadFrom(TypeA&, const TypeB&) { ... }
TypeB& loadFrom(TypeB&, const TypeA&) { ... }

这种重载的编译时多态性的使用意味着每次涉及的变量在支持的类型之间更改时,都不需要更新转换代码。

最新更新