Typedef 到 C++ 中的周围类型
Typedef to surrounding type in C++
有没有办法在声明的(周围的)类型本身的类型声明中构建一个 typedef
而无需声明类型的名称?
示例:
class X
{
public:
typedef <fill in magic here> MyType;
//...
};
背景:
乍一看这似乎很愚蠢。我需要这个,因为我使用宏构建数据 classes 的编译时反射。
所以在数据的声明中插入了一个宏 class 需要处理它插入的类型。
到目前为止,我找到了适用于 MSVC 和 g++ 的可行解决方案,它们都依赖于我认为是实现中的缺陷。所以他们可能无法在较新的版本上工作。
Clang 没有 "eat" 这些解决方案中的任何一个。
我目前的 MSVC 解决方案定义了一个方法,然后仅通过它的名称获取它的地址,并调用一个 "returns" 它的类型 class 的小助手。 (Clang 和 g++ 需要方法的全名,包括它的 class 名称)。
我当前的 g++ 解决方案定义了 return 类型 std::remove_reference(decltype(*this))
的静态方法。 (Clang 和 MSVC 不允许在静态上下文中使用 this
)。
我绝对更喜欢符合标准的解决方案,但目前也可以使用 clang 的特殊解决方案。
如果没有任何效果,我必须将 class' 名称传递给宏,但我尽量避免这种情况,因为我已经有大量使用宏的代码。
编辑:添加一个关于反射如何工作的示例(这可能会阐明我的需要):
class X : public Y
{
public:
//.. constructor and such stuff...
int a;
double b;
std::string c;
CLASSHEAD(Y)
FIELD(a)
FIELD(b)
FIELD(c)
CLASSFOOT
};
CLASSHEAD
是应该定义 typedef
的宏。它是一个 VAR_ARGS 宏,其中参数接收基数 classes。如前所述:可以将 class' 名称作为它的第一个参数(导致示例中的 CLASSHEAD(X, Y)
)。但是我几乎无法想象像 typedef'ing 周围类型这样的 "simply" 任务没有解决方案...
这不完全符合您的规格,但我认为它非常接近:
class X
{
//Stuff...
//Use Macros to add:
struct MyType;
//Use class closing macro to insert variable between class-ending brace and semicolon
} TYPE_VAR;
//Perhaps add random stuff to TYPE_VAR name to avoid collisions, like __FILE__
struct decltype(TYPE_VAR)::MyType
{
typedef decltype(TYPE_VAR) V;
};
然后使用
访问X的类型
X::MyType::V
例如,简化的 CLASSFOOT 可能如下所示:
#define CLASSFOOT /*Your classfoot here*/ } TYPE_VAR; struct decltype(TYPE_VAR)::MyType {typedef decltype(TYPE_VAR) V;
//No }; at end on purpose- this will come from the class in which you placed CLASSFOOT
这对您的目的是否足够好?
由于您已经在使用宏,您可以使用此解决方案
#define CLASS_WITH_MY_TYPE(ClassName) \
class ClassName \
{ \
using MyType = ClassName;
然后用like
CLASS_WITH_MY_TYPE(X)
public:
struct Y
{
using T = MyType;
};
};
static_assert(std::is_same<X, typename X::Y::T>::value, "");
标记为社区维基,因为@Chris 提到了 link 并且原始答案由 @Bartek Banachewicz
发布
Nohting 有效,因此在宏中使用 class 名称是唯一可行的解决方案
有没有办法在声明的(周围的)类型本身的类型声明中构建一个 typedef
而无需声明类型的名称?
示例:
class X
{
public:
typedef <fill in magic here> MyType;
//...
};
背景: 乍一看这似乎很愚蠢。我需要这个,因为我使用宏构建数据 classes 的编译时反射。 所以在数据的声明中插入了一个宏 class 需要处理它插入的类型。 到目前为止,我找到了适用于 MSVC 和 g++ 的可行解决方案,它们都依赖于我认为是实现中的缺陷。所以他们可能无法在较新的版本上工作。 Clang 没有 "eat" 这些解决方案中的任何一个。
我目前的 MSVC 解决方案定义了一个方法,然后仅通过它的名称获取它的地址,并调用一个 "returns" 它的类型 class 的小助手。 (Clang 和 g++ 需要方法的全名,包括它的 class 名称)。
我当前的 g++ 解决方案定义了 return 类型 std::remove_reference(decltype(*this))
的静态方法。 (Clang 和 MSVC 不允许在静态上下文中使用 this
)。
我绝对更喜欢符合标准的解决方案,但目前也可以使用 clang 的特殊解决方案。
如果没有任何效果,我必须将 class' 名称传递给宏,但我尽量避免这种情况,因为我已经有大量使用宏的代码。
编辑:添加一个关于反射如何工作的示例(这可能会阐明我的需要):
class X : public Y
{
public:
//.. constructor and such stuff...
int a;
double b;
std::string c;
CLASSHEAD(Y)
FIELD(a)
FIELD(b)
FIELD(c)
CLASSFOOT
};
CLASSHEAD
是应该定义 typedef
的宏。它是一个 VAR_ARGS 宏,其中参数接收基数 classes。如前所述:可以将 class' 名称作为它的第一个参数(导致示例中的 CLASSHEAD(X, Y)
)。但是我几乎无法想象像 typedef'ing 周围类型这样的 "simply" 任务没有解决方案...
这不完全符合您的规格,但我认为它非常接近:
class X
{
//Stuff...
//Use Macros to add:
struct MyType;
//Use class closing macro to insert variable between class-ending brace and semicolon
} TYPE_VAR;
//Perhaps add random stuff to TYPE_VAR name to avoid collisions, like __FILE__
struct decltype(TYPE_VAR)::MyType
{
typedef decltype(TYPE_VAR) V;
};
然后使用
访问X的类型X::MyType::V
例如,简化的 CLASSFOOT 可能如下所示:
#define CLASSFOOT /*Your classfoot here*/ } TYPE_VAR; struct decltype(TYPE_VAR)::MyType {typedef decltype(TYPE_VAR) V;
//No }; at end on purpose- this will come from the class in which you placed CLASSFOOT
这对您的目的是否足够好?
由于您已经在使用宏,您可以使用此解决方案
#define CLASS_WITH_MY_TYPE(ClassName) \
class ClassName \
{ \
using MyType = ClassName;
然后用like
CLASS_WITH_MY_TYPE(X)
public:
struct Y
{
using T = MyType;
};
};
static_assert(std::is_same<X, typename X::Y::T>::value, "");
标记为社区维基,因为@Chris 提到了 link 并且原始答案由 @Bartek Banachewicz
发布Nohting 有效,因此在宏中使用 class 名称是唯一可行的解决方案