C++ 如何在C++;?

C++ 如何在C++;?,c++,templates,c-preprocessor,c++03,C++,Templates,C Preprocessor,C++03,对于这个特定的项目,我不能使用C++11特性(例如,decltype),因为编译器还不支持它们。我需要能够将当前类作为模板参数提供,最好是在没有参数的宏中提供(见下文),而无需修饰类声明或隐藏大括号等 class Foo: private Bar<Foo> { MAGIC //expands to using Bar<Foo>::Baz; and some others public: void otherFunction(); //.

对于这个特定的项目,我不能使用C++11特性(例如,
decltype
),因为编译器还不支持它们。我需要能够将当前类作为模板参数提供,最好是在没有参数的宏中提供(见下文),而无需修饰
声明或隐藏大括号等

class Foo: private Bar<Foo> {
   MAGIC //expands to using Bar<Foo>::Baz; and some others
   public:
      void otherFunction();
      //... the rest of the class
};
class Foo:私人酒吧{
MAGIC//扩展到使用Bar::Baz;和其他一些工具
公众:
void otherFunction();
//…班上其他人
};
理想情况下,我希望它能像Qt的
Q_OBJECT
宏一样工作,但不引入另一个预编译步骤和相关的生成类
typeid
在运行时可能很有用,但我的目标是在构建时完成所有这一切

如何编写
MAGIC
宏,以避免每次重复类名?

您可以使用“proxy”(?)结构来构建继承:

template <typename S>
struct Base : public S{ //always public, access is restricted by inheriting Base properly
    using super = S;
};
模板
结构基:public S{//always public,通过正确继承基来限制访问
使用super=S;
};
用法如下:

#include <iostream>

template <typename S>
struct Base : public S { 
    using super = S;
};

template <typename T>
class Bar
{
public:
    virtual void f() { std::cout << "Bar" << std::endl;  }
};

class Foo : private Base<Bar<int>>
{
public:
    virtual void f() 
    { 
        std::cout << "Foo";
        super::f();  //Calls Bar<int>::f()
    }
};

class Fii : private Base<Foo>
{
public:
    virtual void f() 
    {
        std::cout << "Fii";  
        super::f(); //Calls Foo::f()
    }
};


int main()
{
    Fii fii;
    fii.f(); //Print "FiiFooBar"
    return 0;
}
#包括
模板
结构基:公共S{
使用super=S;
};
模板
分类栏
{
公众:

virtual void f(){std::cout我认为没有任何语言支持的机制可以从类中提取基类型。您可以使用:

选项1

class Foo: private Bar<Foo> {

#define BASE_TYPE Bar<Foo>
   // Use BASE_TYPE in MAGIC
   MAGIC //expands to using Bar<Foo>::Baz; and some others
#undef BASE_TYPE

   public:
      void otherFunction();
      //... the rest of the class
};
class Foo:私人酒吧{
#定义基本类型栏
//在MAGIC中使用BASE_类型
MAGIC//扩展到使用Bar::Baz;和其他一些工具
#未定义基类型
公众:
void otherFunction();
//…班上其他人
};
选项2

class Foo: private Bar<Foo> {

    typedef Bar<Foo> BASE_TYPE;

   // Use BASE_TYPE in MAGIC
   MAGIC //expands to using Bar<Foo>::Baz; and some others

   public:
      void otherFunction();
      //... the rest of the class
};
class Foo:私人酒吧{
类型定义条形基础_类型;
//在MAGIC中使用BASE_类型
MAGIC//扩展到使用Bar::Baz;和其他一些工具
公众:
void otherFunction();
//…班上其他人
};
关于:

template<typename T>
class Base
{
protected:
    typedef Base<T> MagicBaseType;
    namespace Baz { }
};

class Derived1 : private Base<Derived1>
{
    using MagicBaseType::Baz;
}


class Derived1 : private Base<Derived2>
{
    using MagicBaseType::Baz;
}
模板
阶级基础
{
受保护的:
typedef基MagicBaseType;
名称空间Baz{}
};
类Derived1:私有基
{
使用MagicBaseType::Baz;
}
类Derived1:私有基
{
使用MagicBaseType::Baz;
}
或者,如果无法修改基本定义,请使用模板和多重继承

template<typename T>
class Base
{
protected:
    namespace Baz { }
};

template<typename T>
class DerivedTemplate : public T
{
protected:
    typedef typename T BaseType;
}

class Derived : public Base<Derived>, public DerivedTemplate<Base<Derived>>
{
using BaseType::Baz;
}
模板
阶级基础
{
受保护的:
名称空间Baz{}
};
模板
类派生模板:public T
{
受保护的:
typedef typename T BaseType;
}
派生类:公共基、公共派生模板
{
使用BaseType::Baz;
}

如果您真的不关心格式化或编写维护问题,您可以通过让宏使用type参数来执行此操作,而无需重复类型:

#define MAGIC(BASE) \
BASE { \
    using BASE::baz;

class Sub : private MAGIC(Base<Foo>)

  public:
    void otherFunction();
};
#定义魔术(基础)\
碱基{\
使用BASE::baz;
职业分类:私人魔术(基础)
公众:
void otherFunction();
};

但这让我对自己感觉很糟糕

这个问题似乎是C++03版本的“”如果我把标题改成基本C++,那么封闭类让你听起来像是嵌套,什么类型是外部类。“<代码>自我>代码>问题看起来非常相似,但是它不像你所说的任何C++中所建议的解决方案。如果它能使它更清楚,当然可以改变标题。k哪一个基本属性?我的2美分是:它可能是不可能的,而不是为一个没有为它设计的宏系统提供强大的武装,或者通过Perl脚本运行你的代码;或者找到一个使用C++的不同解决方案(例如使用唯一的int作为模板参数,而不是类型名)。。您可以通过在类声明之前定义
ing
BASE\u TYPE
来避免冗余,因此您可以说
class Foo:private BASE\u TYPE
。或者将其保留在类中并使用
typedef
而不是像
typedef Bar BaseType那样定义
@RyanHaining,这就是为什么我有
\undef
就在
MAGIC
行之后。