using 关键字的应用场景
using 关键字在 C++ 中由来已久,使用得也比较多,现代 C++ 进一步扩展了其应用范围,目前 using 可以用在以下场景中:
- 命名空间声明
- 命名空间成员声明
- 类成员声明
- 类继承构造
- 类型别名与模板别名
其中的 4,5 是现代 C++ 对 using 关键字应用范围的扩展,5 是用来替代 typedef 的。
代码示例 :
#include
#include
template class MagicType {
public:
T dark;
U magic;
};
template
using TrueDarkMagic = MagicType; // using template alias declaration
int main(void) {
// case 1: namespace declaration
using namespace std::filesystem;
// case 2: namespace member declaration
using std::cout, std::endl;
// case 3, 4: class member declaration, inherited constructor
struct B {
B() : x_{0} {};
B(int y) : B() { y_ = y; }; // use delegating constructor
void print() const { cout << '[' << x_ << ", " << y_ << "]
"; };
void print(bool) const { cout << '{' << x_ << ", " << y_ << "}
"; };
private:
int x_;
int y_;
};
// private inheritance
struct D : private B {
using B::B; // case 4: inherited constructor
using B::print; // case 3: class member declaration
};
D d{6};
d.print(); // [0, 6]
d.print(true); // {0, 6}
// case 5: type alias and alias template declaration
#define Dstring std::string
typedef std::string Tstring;
using Ustring = std::string;
typedef void (*TFP)(int, const std::string &); // typedef type alias declaration
using UFP = void (*)(int, const std::string &); // using type alias declaration
TrueDarkMagic tdm; // using template alias declaration
return 0;
}
/
注意上面的代码还用到了现代 C++ 的 委托构造与继承构造 新特性
using 与 typedef
现代 C++ 扩展了 using 关键字的语义,其中就包含了对 typedef 的替换,那 C++ 在设计上为啥不直接扩展 typedef 呢?这个是为了兼容 C,谁也不能保证将来 C 会不会扩展 typedef。因此,在 C++ 编程中推荐无脑的使用 using 关键字,遇到使用 typedef 的老代码也要能看得懂,知道怎么使用 using 来改善。
#include
template class MagicType {
public:
T dark;
U magic;
};
template struct TrueDarkMagic0 {
typedef MagicType type; // typedef
};
template
using TrueDarkMagic1 = typename TrueDarkMagic0::type; // using with typename
template using TrueDarkMagic2 = MagicType; // using
#if 0
template
typedef MagicType TrueDarkMagic3; // not compiles
#endif
int main(void) {
using std::cout, std::is_same_v;
cout.setf(std::ios_base::boolalpha);
// case 1: using is more clear than typedef
typedef void (*TFP)(int, const std::string &); // typedef
using UFP = void (*)(int, const std::string &); // using
// case 2: alias template declaration
TrueDarkMagic0::type tdm0;
TrueDarkMagic1 tdm1;
TrueDarkMagic2 tdm2;
cout << is_same_v << '
'; // true
cout << is_same_v << '
'; // true
// case 3: C++ type_traits also use using prefer to typedef
// template using remove_const_t = typename remove_const<_Tp>::type;
const int x0 = 1;
const int y0 = 1;
std::remove_const::type x00 = 1;
std::remove_const_t y00 = 1;
cout << is_same_v << '
'; // true
cout << is_same_v << '
'; // true
return 0;
}
/
'using' 用起来确实要比 'typedef' 要方便,标准库也在大量使用 'using' 来改善老的 'typedef' 设计
总结
- typedef 不能直接定义模板别名,需要定义额外的模板类来支持
- using 是更好的 typedef,推荐使用 using 来改善老的 typedef 设计
- 也要注意 using 的其它应用特性
|