typeof运算符的情况下在C + + 03? [英] Absence of typeof operator in C++03?

查看:131
本文介绍了typeof运算符的情况下在C + + 03?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是想知道如何提升已实现 BOOST_TYPEOF (在C ++中03),这似乎是一个非常有用的工具。任何人有任何想法?

I'm just wondering how boost have implemented BOOST_TYPEOF (in C++03) which seems to be a very useful tool. Anyone has any idea?

另外,我想C ++ 03本身也提供了的typeof 运营商,尤其是当它已经有的sizeof(表达式)其中的必须被知道的键入的的 EXPR 还,否则怎么还能它告诉我们在尺寸的,不知道的键入的?难道真的有可能知道的的尺寸的,不知道的键入的一个前pression?

Also, I'm thinking C++03 itself could have provided typeof operator, especially when it already has sizeof(expr) which must be knowing the type of the expr also, otherwise how else could it tell us the size, without knowing the type?Is it really possible to know the size, without knowing the type of an expression?

如果不知道的键入的,那么编译器告诉我们的的尺寸的东西(如果没有的<​​em>键入的)?我的意思是,的sizeof(unknowntype)就没有意义的编译器(和人类一样)!

If it doesn't know the type, then compiler tells us the size of what (if not type)? I mean, sizeof(unknowntype) wouldn't make sense to the compilers (and humans as well)!

推荐答案

它只是使用编译器的魔法。就像,GCC的 __ __ typeof运算。对于编译器不提供这样的魔力,它提供了可检测的部分的前pressions类型的仿真,但失败并完全未知类型。

It just uses compiler magics. Like, GCC's __typeof__. For compilers that don't provide such magic, it provides an emulation that can detect the type of some expressions, but fails with completely unknown types.

一个可能的实现可以以具有接受一个给定类型的一个前pression,然后从该类型分派到使用类模板的号码的功能的列表。为了使函数模板返回数字作为一个编译时的实体,我们把它放到一个数组尺寸

A possible implementation could be to have a list of functions that accept an expression of a given type, and then dispatch from that type to a number using a class template. To make the function template return the number as a compile time entity, we put it into an array dimension

template<typename> struct type2num;
template<int> struct num2type;
template<typename T> typename type2num<T>::dim &dispatch(T const&);

然后从这个数字可以追溯到类型,所以我们的 EMUL_TYPEOF 可以直接命名的类型。因此,要注册类型,我们写

Then it goes from that number back to the type, so that our EMUL_TYPEOF could directly name the type. So to register a type, we write

#define REGISTER_TYPE(T, N) \
  template<> \
  struct type2num<T> { \
    static int const value = N; \
    typedef char dim[N]; \
  }; \
  template<> \
  struct num2type<N> { typedef T type; }

在地方到这一点,你可以写

Having this in place, you can write

#define EMUL_TYPEOF(E) \
  num2type<sizeof dispatch(E)>::type

每当你需要注册一个类型,你写

Whenever you need to register a type, you write

REGISTER_TYPE(int, 1);
REGISTER_TYPE(unsigned int, 2);
// ...

当然,现在你发现你需要一种机制来接受矢量&lt; T&GT; ,你不知道 T 提前,然后它得到任意复杂。您可以创建一个系统,如果数字的含义不仅仅是一个类型的更多。这或许可以工作:

Of course, now you find you need a mechanism to accept vector<T>, where you don't know T in advance and then it gets arbitrary complex. You could create a system where the numbers mean more than just a type. This could probably work:

#define EMUL_TYPEOF(E) \
  build_type<sizeof dispatch_1(E), sizeof dispatch_2(E)>::type

这可以检测类型,如 INT ,并类型,如的shared_ptr&LT; INT&GT; - 换句话说,类型的不是类模板特,并与一个模板参数类模板特,做一些系统性的映射

This could detect types like int and also types like shared_ptr<int> - in other words, types that aren't class template specializations, and class template specializations with one template argument, by doing some kind of systematical mapping


  • 如果第一数目产生1,第二个数字指定一个种类;否则

  • 的第一个号码指定一个模板,第二个数字的第一种类型的模板参数

所以,这成为

template<int N, int M>
struct build_type {
  typedef typename num2tmp<N>::template apply<
    typename num2type<M>::type>::type type;
};

template<int N>
struct build_type<1, N> {
  typedef num2type<N>::type type;
};

我们还需要修改调度模板,并在两个版本分裂它,如下图所示,沿着 REGISTER_TEMP1 用于注册一个参数模板

We also need to change the dispatch template and split it up in two versions, shown below, alongside the REGISTER_TEMP1 for registering one-argument templates

template<typename T> typename type2num<T>::dim1 &dispatch_1(T const&);
template<typename T> typename type2num<T>::dim2 &dispatch_2(T const&);

#define REGISTER_TYPE(T, N) \
  template<> \
  struct type2num<T> { \
    static int const value_dim1 = 1; \
    static int const value_dim2 = N; \
    typedef char dim1[value_dim1]; \
    typedef char dim2[value_dim2]; \
  }; \
  template<> \
  struct num2type<N> { typedef T type; }

#define REGISTER_TMP1(Te, N) \
  template<typename T1> \
  struct type2num< Te<T1> > { \
    static int const value_dim1 = N; \
    static int const value_dim2 = type2num<T1>::value_dim2; \
    typedef char dim1[value_dim1]; \
    typedef char dim2[value_dim2]; \
  }; \
  template<> struct num2tmp<N> { \
    template<typename T1> struct apply { \
      typedef Te<T1> type; \
    }; \
  }

注册的std ::矢量模板,既 INT 变种现在的样子

Registering the std::vector template and both int variants now look like

REGISTER_TMP1(std::vector, 2);
// ... REGISTER_TMP1(std::list, 3);

REGISTER_TYPE(int, 1);
REGISTER_TYPE(unsigned int, 2);
// ... REGISTER_TYPE(char, 3);

您可能还需要与每种类型注册多个数字,常量/挥发性的每个组合一个数字或可能需要每个类型的多个号码记录 * &安培; 和这样的。你也想​​支持矢量&lt;矢量&lt;诠释&GT; &GT; ,所以你需要的模板参数多于一个的人数太多,使得 build_type 递归调用自身。正如你可以创建反正整数,你可以带code任何东西到该序列的任意长的列表,所以它只是为什么要在如何重新present这些东西你的创造力。

You probably also want to register multiple numbers with each type, one number for each combination of const/volatile or may need more than one number per type for recording *, & and such. You also want to support vector< vector<int> >, so you need more than one number for the template argument too, making build_type call itself recursively. As you can create an arbitrary long list of integers, you can encode anything into that sequence anyway, so it's just up to your creativity on how to represent these things.

在最后,你可能重新实现BOOST_TYPEOF:)

In the end, you are probably reimplementing BOOST_TYPEOF :)

这篇关于typeof运算符的情况下在C + + 03?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆