检查类是否具有 typedef(私有或其他)的特征 [英] Trait which checks whether class has typedef (private or other) or not

查看:42
本文介绍了检查类是否具有 typedef(私有或其他)的特征的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法检查 class 是否有一个 typedef 甚至适用于 private typedef?

Is there a way to check if class has a typedef which works even for private typedef?

以下代码在 VS2013 中有效,但在 ideone 的 gcc

Following code works in VS2013, but fails on ideone's gcc

template<typename T>
struct to_void
{
    typedef void type;
};

class Foo
{
    typedef int TD;
};

template <typename T, typename dummy = void>
struct has_TD : std::false_type {};

template <typename T>
struct has_TD<T, typename to_void<typename T::TD>::type > : std::true_type{};

int main()
{
    std::cout << std::boolalpha << has_TD<Foo>::value << std::endl;
}

编辑 - 为什么我想要这个

我有自定义序列化系统,可以序列化任意类型.当它的行为必须不同时(例如字符串),它有几个重载.对于其余类型,它只是将值写入内存.如果我有组合类型,我有时也可以只写入内存(保存和加载发生在相同的体系结构上,使用相同的编译器编译,因此填充将相同,等等).例如,此方法对 POD 类型(std::is_pod trait)有效,但所有 POD 类型只是所有类型的子集,支持此序列化.

I have custom serialization system, which can serialize arbitrary type. It has several overloads when it must behave differently (for example string). For the rest of the types, it simply writes the value in the memory. If I have composed type, I can sometimes just write into memory as well (save & load happens on the same architecture, compiled with the same compiler, so paddings will be the same, etc.). This method is valid for example for POD types (std::is_pod trait), but all POD types is only a subset of all types, supporting this serialization.

所以我基本上有模板函数 write<T> 只写 sizeof(T) 字节(原始序列化)......但我不想要这个被错误调用,我希望用户在他们的类中明确地说:这个类/结构可以被原始序列化").我这样做的方法是一个宏 ALLOW_RAW_SERIALIZE ,它定义了一些可以通过特征检查的 typedef.如果类 MyClass 不包含 typedef,调用 write(myClassInstance) 将产生编译器错误.

So I basically have templated function write<T> which just write sizeof(T) bytes (raw-serialization)... But I don't want this to be called by mistake, I want user, to explicitly say in their class: "this class/struct can be raw-serialized"). The way I do it is a macro ALLOW_RAW_SERIALIZE which defines some typedef which can be checked via trait. If class MyClass doesn't contains typedef, calling write(myClassInstance) will produce compiler error.

基本上决定类是否可以原始序列化的是它的成员(没有反射,成员不能被自动枚举和检查,所以用户必须提供这些信息).典型的类看起来像这样:

The things which which basically decide if class can be raw-serialized are its members (without reflection, members cannot be enumerated and checked automatically, so user have to provide such information). typical class looks like this:

class
  public
    ctor-dtor
    methods
  private
    methods
    members

并且我希望用户允许编写 ALLOW_RAW_SERIALIZE 尽可能靠近成员,因此当他们更改某些成员时,忘记更新ALLOW_RAW_SERIALIZE 的可能性较小(删除它.当它不再有效时)

and I want users to allow write ALLOW_RAW_SERIALIZE as close to the members as possible, so when they change some members there is a lesser chance to forgot about updating ALLOW_RAW_SERIALIZE (remove it. when it's no longer valid)

所以这就是为什么我要检查 private typedef

So that is why I want to check a private typedef

由于它是反射的替代品,并且需要整个类型并编写它,因此我不会像打破封装那样陷入困境......

Since it's substitute for reflection and takes whole type and write it, I don't fell about it like breaking encapsulation or so...

推荐答案

更新:

好的,做了一些研究.

仅供参考,ideone 未编译的 [可能] 原因是您正在做的事情需要 -std=c++11 [或更高].在添加之前我遇到了类似的错误.但是,我不得不使用 clang++,因为如果 TDprivateg++ 仍然有编译问题.

FYI, the [probable] reason that ideone didn't compile is that what you're doing needs -std=c++11 [or higher]. I got similar errors before adding that. But, I had to use clang++ as g++ still had problems compiling if TD was private.

但是,我不确定这是否有效,因为唯一打印为 true 的组合是 TD 是否公开.所有其他公共/私有以及将 TD 更改为 TF 都产生错误.也许 VS2013 有效 [为什么?],但另外两个编译器在编译或运行时结果方面存在问题——YMMV.

But, I'm not sure this works as the only combo that printed true was if TD was public. All others of public/private and changing TD to TF produced false. Maybe VS2013 works [why?], but two other compilers have issues, either in compilation or runtime results--YMMV.

您所做工作的基础是 std::integral_constant [自 c++11].对于您正在做的事情,似乎没有标准的推导.即,来自 http://www.cplusplus.com/reference/type_traits/integral_constant/ [左侧] 的类型特征列表没有与您的用例 [AFAICT] 匹配的内容.

The basis for what you're doing is std::integral_constant [since c++11]. There appears to be no standard derivation from this for what you're doing. That is, from http://www.cplusplus.com/reference/type_traits/integral_constant/ the list of type traits [on the left] has nothing that matches your use case [AFAICT].

Boost.TypeTraits 也没有任何匹配的东西 [再次,AFAICT].

Nor does Boost.TypeTraits have anything that matches up [again, AFAICT].

来自 Andrei Alexandrescu 的书:现代 C++ 设计:应用的泛型编程和设计模式",第 2.10 节类型特征:

From Andrei Alexandrescu's book: "Modern C++ Design: Generic Programming and Design Patterns Applied", section 2.10 Type Traits:

通常,您将根据通用代码的需要编写自己的特征模板和类.但是,某些特征适用于任何类型.它们可以帮助通用程序员更好地根据类型的功能定制模板代码.

Usually, you will write your own trait templates and classes as your generic code needs them. Certain traits, however, are applicable to any type. They can help generic programmers to tailor template code better to the capabilities of a type.

因此,如果您愿意,可以自己动手".

So, it's "okay" to roll your own, if you wish.

但是,即使是他 [来自 Loki] 谈到的 TypeTraits,也没有任何与您正在做的事情相匹配的内容.

But, even the TypeTraits he talks about [from Loki], again, doesn't have anything that matches what you're doing.

既然 stdBoost 都没有任何东西,那么问题就变成了什么是标准?"[从你的角度来看].某处可能有fludger"c++ 特征库有一个实现,但这会被认为是标准的"吗?赞一个

Since neither std nor Boost has anything, then the question becomes "what is standard?" [from your perspective]. There may be "fludger" c++ traits library somewhere that has an implementation, but would that be considered "standard"? YMMV

但是,一两个问题:

为什么要这样做?它有什么用?基类中的受保护 typedef 怎么样?

Why would one do this? What is the use for it? What about a protected typedef in a base class?

而且,这似乎需要了解类的私有部分,这不会违反数据隐藏"或封装[没有某种 friend 声明]?

And, this seems to require knowledge of the private part of a class, and wouldn't that be a violation of either "data hiding" or encapsulation [without a friend declaration of some sort]?

所以,如果最后一个问题是真的,那么 [IMO] 可能的答案是没有标准方法可以做到这一点,因为这不是人们应该在标准库中进行.

So, if that last question is true, the probable [IMO] answer is that there is no standard way to do this, because it's not something one should be doing in a standard library.

旁注:这是被否决的部分(在我[真正]理解问题之前).我相信我已经无罪释放了.所以,请忽略下面的答案.

Side note: This is the part that got downvoted (before I [truly] understood the question). I believe I've acquitted myself above. So, disregard the answer below.

当您使用 class 时,默认 可见性是 private.使用 struct,它是 public.

When you use class the default visibility is private. With struct, it's public.

所以,要么做:

struct Foo

或者:

class Foo
{
    public:
    typedef int TD;
};

当然,这是假设您希望 TD成为public

This is, of course, assuming that you want TD to be public

这篇关于检查类是否具有 typedef(私有或其他)的特征的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆