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



下面的代码显示了类 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 )实例都成为SomethingElseC

我认为这个要求无法满足,因为SomethingElseC构造函数具有不同的签名,所以我不能只做:

#ifdef DEBUG
#define B SomethingElse
#else
#define B C
#endif

是否有 C 预处理器专家可以确认是否有办法满足要求?是否可以创建一个宏,以便在编译时可以将B的所有现有实例交换为SomethingElseC的实例化?您可以假设要C的第二个和第三个参数将是__FILE____LINE__

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

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

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

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

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

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

最新更新