我可以使用预处理器将一个类型声明替换为另一个吗?

时间:2018-01-31 22:34:59

标签: c++ macros

以下代码显示了课程ABCABC的ctor参数。

X有条件地创建AB个实例。

#include <iostream>

class A
{
};

class B
{
public:
  B( const A& a ) : a_( a ) { std::cout << __FUNCTION__ << std::endl; }
private:
  const A& a_;
};

class C
{
public:
  C( const A& a, const std::string& file, int line )
    : b_( ( (std::cout << "@ " << file << ":" << line << std::endl), a ) )
  {
    std::cout << "After" << std::endl;
  }
private:
  B b_;
};

#undef DEBUG
#ifdef DEBUG
#define X( Z ) B b##Z( Z )
#else
#define X( Z ) C c##Z( Z, __FILE__, __LINE__ )
#endif

int main( int argc, char* argv[] )
{
  A a;
  B b( a );
  C c( a, __FILE__, __LINE__ );
  X( a );
  return 0;
}

我被要求将B重命名为SomethingElse并创建一个B宏,以便B b( a )的所有现有实例变为SomethingElse或{ {1}}。

我不认为这个问题可以得到满足,因为CSomethingElse构造函数有不同的签名,所以我不能这样做:

C

是否有C预处理专家可以确认是否有办法满足要求?可以创建宏,以便#ifdef DEBUG #define B SomethingElse #else #define B C #endif 的所有现有实例都可以在编译时交换到BSomethingElse的实例化吗?您可以假设C的第二个和第三个参数为C__FILE__

2 个答案:

答案 0 :(得分:4)

一旦你意识到C ++继承实现了一个IS-A关系,这是相当容易的。

您定义了一个新的类realB<const str* FILE, int LINE>,其中IS-A(派生自)CSomethingElse。您需要的唯一小技巧是帮助constexpr const char*捕获__FILE__,请参阅here

现在realB<FILE, LINE>有一个ctor只有一个参数A a,但如果它继承自C,它仍然可以将(a, FILE, LINE)传递给C::C < / p>

答案 1 :(得分:0)

我在手机上,所以这是未经测试的,但您可以尝试:

#if DEBUG
#  define CREATEB(a) somethingelse(a)
#else
#  define CREATEB(a) C( (a), __FILE__, __LINE__ )
#endif

这些应该在auto或引用到基类声明的右侧工作。