伪造静态If在C++中

B.S*_*.S. 8 c++ optimization static if-statement static-if

我正在测试各种优化的组合,对于这些,我需要一个静态的,如果在描述http://channel9.msdn.com/Events/GoingNative/GoingNative-2012/Static-If-I-Had-a-Hammer启用并禁用特定的优化.if(const-expr)并不总是有效,因为某些优化涉及更改数据布局,而这在功能范围内无法完成.

基本上我想要的是这个:

template<bool enable_optimization>
class Algo{
  struct Foo{
    int a;
    if(enable_optimization){
      int b;
    }

    void bar(){
      if(enable_optimization){
        b = 0;
      }
    }
  };
};
Run Code Online (Sandbox Code Playgroud)

(是的,在我的情况下,从数据布局中删除b的较小内存占用量是相关的.)

目前我正在使用非常糟糕的黑客伪装它.我正在寻找一种更好的方法.

档案啊

#ifndef A_H
#define A_H
template<class enable_optimization>
class Algo;
#include "b.h"
#endif
Run Code Online (Sandbox Code Playgroud)

文件bh(此文件是从Python脚本自动生成的)

#define ENABLE_OPTIMIZATION 0
#include "c.h"
#undef
#define ENABLE_OPTIMIZATION 1
#include "c.h"
#undef
Run Code Online (Sandbox Code Playgroud)

文件ch

template<>
class Algo<ENABLE_OPTIMIZATION>{
  struct Foo{
    int a;
    #if ENABLE_OPTIMIZATION
    int b;
    #endif

    void bar(){
      #if ENABLE_OPTIMIZATION
      b = 0;
      #endif
    }
  };
};
Run Code Online (Sandbox Code Playgroud)

有谁知道更好的方法吗?从理论上讲,它可以使用模板元编程完成,起初我使用它.至少我使用它的方式是屁股的痛苦,并导致完全不可读和臃肿的代码.使用上面的hack可以显着提高生产力.

编辑:我有几个优化标志,这些互动.

Jon*_*ely 6

没有理由使用模板使代码变得更加复杂:

template<bool enable_optimization>
  class FooOptimized
  {
  protected:
    int b;
    void bar_optim()
    {
      b = 0;
    }
  };

template<>
  class FooOptimized<false>
  {
  protected:
    void bar_optim() { }
  };

template<bool enable_optimization>
  struct Algo
  {
    struct Foo : FooOptimized<enable_optimization>
    {
      int a;

      void bar()
      {
        this->bar_optim();
      }
    };
  };
Run Code Online (Sandbox Code Playgroud)

不需要元编程,只需根据优化是否启用为新类型并将其专门化来区分不同的部分.

因为新类型在它为空时用作基类(即没有FooOptimized::b成员),所以它不会占用空间sizeof(Algo<false>::Foo) == sizeof(int).


(可以随意忽略这个答案的其余部分,它没有直接解决问题,而是建议采用不同的方法进行不同的权衡.是否"更好"与否取决于真实代码的细节,在问题中给出的小例子中没有显示.)

作为一个相关的,但独立的问题上,各部分AlgoAlgo::Foo取决于优化是否启用仍依赖模板参数,所以虽然你只写这些代码位一次,编译器将产生两套目标代码.根据代码中的工作量以及它的使用方式,您可能会发现将其更改为非模板代码是有利的,即用动态多态替换静态多态.例如,您可以使enable_optimization标志成为运行时构造函数参数而不是模板参数:

struct FooImpl
{
  virtual void bar() { }
};

class FooOptimized : FooImpl
{
  int b;
  void bar()
  {
    b = 0;
  }
};

struct Algo
{
  class Foo
  {
    std::unique_ptr<FooImpl> impl;
  public:
    explicit
    Foo(bool optimize)
    : impl(optimize ? new FooOptimized : new FooImpl)
    { }

    int a;

    void bar()
    {
      impl->bar();
    }
  };
};
Run Code Online (Sandbox Code Playgroud)

你必须来分析和测试,以确定虚函数是否有更多的比的代码复制开销少Algo并且Algo::Foo不依赖于模板参数.