c++ - 如何实现BOOST_TYPEOF?

标签 c++ boost types

这里我想了解实现BOOST_TYPEOF的大致思路。我的意思是代码可能没问题,但我想代码不会像真正的 Boost 实现那样简单。因此,我想了解 BOOST_TYPEOF 实现的想法。它是否使用编译器函数(一些 API)来理解编译时表达式的类型?

最佳答案

在核心,Boost::Typeof 使用sizeof 非求值上下文将表达式的类型转换为整数,然后再将其转换回类型。

考虑:

template<int N> struct sizer { char value[N]; };

sizer<1> encode(char);
sizer<2> encode(unsigned char);
sizer<3> encode(signed char);
sizer<4> encode(bool);
...

template<int N> struct decode {};
template<> struct decode<1> { typedef char type; };
template<> struct decode<2> { typedef unsigned char type; };
template<> struct decode<3> { typedef signed char type; };
template<> struct decode<4> { typedef bool type; };

#define TYPEOF(expr) decode<sizeof(encode(expr))>::type

现在,给定一个计算结果为任何 char 类型或 bool 的表达式,我们可以这样写:

TYPEOF(expr) var = expr;

Boost::Typeof 本质上是这个想法的扩展,它最初是由 Brian Parker 在 1997 年发明的;见A Portable "typeof" Operator讨论这个想法的历史。


模板对于这个方案来说有点问题;像 std::pair 这样简单的东西给出了类型空间的平方,甚至在递归之前。 Boost::Typeof 通过将模板类型及其参数类型编码到编译时链表的连续槽中来解决这个问题:

template<typename List> struct sizer {
    char item0[List::at<0>];
    char item1[List::at<1>];
    char item2[List::at<2>];
    ...
};

template<typename List> struct encode_type<List, char>: append<List, 1> {};
template<typename List> struct encode_type<List, unsigned char>: append<List, 2> {};
template<typename List, typename S, typename T>
struct encode_type<List, std::pair<S, T> >:
    encode_type<encode_type<append<List, 99>, S>, T> {};

template<typename Iter> struct decode_type<1, Iter> {
    typedef char type;
    typedef Iter iter;
};
template<typename Iter> struct decode_type<2, Iter> {
    typedef unsigned char type;
    typedef Iter iter;
};
template<typename Iter> struct decode_type<99, Iter> {
    typedef typename decode_type<Iter::next::value, Iter::next>::type S;
    typedef typename decode_type<Iter::next::value, Iter::next>::iter S_iter;
    typedef typename decode_type<S_Iter::next::value, S_Iter::next>::type T;
    typedef typename decode_type<S_Iter::next::value, S_Iter::next>::iter T_iter;
    typedef std::pair<S, T> type;
    typedef T_iter iter;
};

template<typename List, typename T>
sizer<typename encode_type<List, T>::type> encode(const T&);

template<typename List> struct decode {
    typedef typename decode_type<List::begin::value, List::begin>::type type; };

#define TYPEOF(expr) decode<list<
    sizeof(encode(expr).item0),
    sizeof(encode(expr).item1),
    sizeof(encode(expr).item2),
    ...
    > >::type

这假定了一个现有的编译时链表实现。您会注意到 std::pair 的解码器根据其参数类型的需要从列表迭代器中消耗尽可能多的项目;这本质上是用具有非可变类型的语言直接翻译等效功能代码。

在标记为省略号 ... 的两行中,我们被限制在类型复杂性的固定级别(即构成我们要推导的类型的模板和类型的数量)。 Boost::Typeof 对此限制的默认值为 50,但可以让您降低它以 boost 效率或增加它以用于极其复杂的程序。

关于c++ - 如何实现BOOST_TYPEOF?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12199280/

相关文章:

java - 理解 Kadane 的二维数组算法

boost - 如何在 Visual Studio 2017 中为 CMake 指定 Boost 位置

c++ - Visual C++ 9.0 (2008) 静态库 + Boost 库 = 大型 .lib 文件

c - 奇怪的不兼容指针类型错误

class - 在 Haskell 中,你可以创建类的对象吗?

c++ - 构建 gcc-4.8.2 时如何理解这些可怕的错误?

C++如何知道数字是否以某种位模式结尾

c++ - 初始化依赖于另一个类成员的类成员

c++ - 在 C++ Builder 中编译 Boost 库时的警告

c++ - 验证整数输入 C++?