【问题标题】:sizeof(...) = 0 or conditional variable declaration in c++ templatessizeof(...) = 0 或 C++ 模板中的条件变量声明
【发布时间】:2010-02-19 00:14:05
【问题描述】:

假设我有这样的事情:

struct EmptyClass{};
template<typename T1, typename T2 = EmptyClass,
         typename T3 = EmptyClass, typename T4 = EmptyClass,
         ..., typename T20> class PoorMansTuple {
  T1 t1;
  T2 t2;
  ...
  T20 t20;
};

现在,每个 PoorMansTuple 最多可能浪费 19 个字节。

问题是:

1) 有没有办法创建一个大小为 0 的类?

2) 有没有办法有条件地定义一个变量?类似的东西:

  T1 t1;
  if (T2 != EmptyClass) T2 t2; // pseudo code
  if (T3 != EmptyClass) T3 t3; // ...

谢谢!

黑魔法宏的使用是有前提的。

我在 MacOSX 上使用 g++。

【问题讨论】:

  • 您能稍微备份一下并更一般地告诉我们您要做什么吗?对于您的一般问题,可能有更简单的解决方案。

标签: c++ templates conditional sizeof


【解决方案1】:

部分专业化可能是您在问题的第一部分寻找的内容。这个程序

#include <string>
#include <iostream>

struct EmptyClass {};

template<typename T1, typename T2>
class Tuple
{
   T1 t1;
   T2 t2;
};

template<typename T1>
class Tuple <T1, EmptyClass>
{
   T1 t1;
};


int main (void)
{
    Tuple<std::string, std::string> two;
    Tuple<std::string, EmptyClass> one1;
    Tuple<std::string> one2;

    std::cout << "<string, string>: " << sizeof(two) << std::endl;
    std::cout << "<string, empty> : " << sizeof(one1) << std::endl;
    std::cout << "<string>        : " << sizeof(one2) << std::endl;

    return 0;
}

打印

<string, string>: 32
<string, empty> : 16
<string>        : 16

【讨论】:

  • (+1) 您可以通过从 1 元组派生 2 元组来减少所需的代码量 - 这样您只需在 2 元组中定义 T2 t2;。概括地说,您只需要通过从 n 元组派生来为每个 (n+1) 元组定义一个成员。
【解决方案2】:

1) 不,因为类的实例不能有内存地址。它至少需要 1 个字节才能有一个地址。 -- 也就是说,没有任何实例和直接引用的类(例如仅在模板生成时使用)将没有大小,因为它不在编译的程序中。

2) 不是没有宏...或者可能是只有 boost.org 忍者才能掌握的晦涩的模板黑色艺术。我听说过编译时“if”的想法,但它目前不在任何即将到来的语言 AFAIK 标准中。那本来可以的。如前所述,也许有一个技巧可以做到。

【讨论】:

    【解决方案3】:
    1. 一个类必须有一定的大小(至少一个)。见“What Is the Smallest Object Size Possible in C/C++?
    2. AFAIK,不,你不能。

    【讨论】:

      【解决方案4】:

      查看boost::tupleboost::compressed_pair。一个类的大小不能为 0,但有“空基类”优化的概念。嗯,我只是要链接到我以前的答案之一,这与 IMO 非常相关:What is std::pair?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-09
        • 2010-10-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多