如果仔细读了标准库的各种api,就会发现,其中很多东西是无法自举的,或者说不满足这个语言本身的语法规范。c++标准库里的许多模板函数,是没法用c++代码写出来的,你自己写代码山寨,是山寨不出这些函数的。只能把代码写在编译器里,让编译时用黑魔法来实现。所以这些模板函数,在头文件里只看得到声明,看不到实现,然而语言标准里,模板函数必须开放实现,不允许只有个声明……所以这些接口就只能由编译器来实现,而不能说定义一个规范让用户自己写——用户不改编译器,把代码填到编译器里的话,自己写一个库,是不可能写出这些功能的。所以做编译器时,就必须自己也做一个标准库,把这些没法自举的模板函数用黑魔法实现。当然,也有的编译器没自己写标准库,而是用操作系统原生编译器的库,但那样也很麻烦,得一个个系统手动适配对方的的黑魔法,识别出对方的这些没法自举的函数最后把调用转发到什么鬼地方,然后自己在编译时把它填好,而不是报未定义错误。
// STRUCT TEMPLATE is_union
template <class _Ty>
struct is_union : bool_constant<__is_union(_Ty)> {}; // determine whether _Ty is a union
template <class _Ty>
_INLINE_VAR constexpr bool is_union_v = __is_union(_Ty);
比如这个,是VC标准库msvcrt里的std::is_union。这个模板函数是没法用c++语法手动写出来的,也就是没法自举,所以标准库里就只是把它的调用转发到了一个根本连声明都追溯不到的__is_union里,相当于额外扩展了一个叫做__is_union的关键字,然后编译器把这个关键字用黑魔法实现……假装自己没有添加关键字,而是写得模板。所以如果某个第三方编译器想用msvcrt而不是自己写,那么就得自己用黑魔法实现__is_union,避免编译时报错。而且还得紧跟VC更新,免得它某个版本不叫__is_union了于是又编译不对了。
评论说boost loki也能做type_trait,让我们看看他们是怎么做的,就看最新版的boost文档里怎么写的:
Compiler Compatibility: Without (some as yet unspecified) help from the compiler, we cannot distinguish between union and class types using only standard C++, as a result this type will never inherit from true_type, unless the user explicitly specializes the template for their user-defined union types, or unless the compiler supplies some unspecified intrinsic that implements this functionality. Currently (June 2015) compilers more recent than Visual C++ 8, clang, GCC-4.3, Greenhills 6.0, Intel-11.0, and Codegear have the necessary compiler intrinsics to ensure that this trait "just works". You may also test to see if the necessary intrinsics are available by checking to see if the macro
BOOST_IS_UNION
is defined.
注意第一句话
Without (some as yet unspecified) help from the compiler, we cannot distinguish between union and class types using only standard C++, as a result this type will never inherit from true_type
所以嘛,装啥装,你照样是编译器非标扩展套个壳子假装自己是模板,和我最后一段说的第三方标准库一样的做法,把编译器原生的STL接口改头换面套了层皮假装是自己写的,吃力不讨好+脱裤子放屁。
网友评论