c++ - 检查类是否具有 typedef(私有(private)或其他)的特征

标签 c++ typetraits

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

以下代码在 VS2013 中有效,但在 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 特征)有效,但所有 POD 类型只是所有类型的子集,支持此序列化。

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

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

class
  public
    ctor-dtor
    methods
  private
    methods
    members

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

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

因为它是反射的替代品并且需要整个类型并编写它,所以我不会像破坏封装那样对它感到失望......

最佳答案

更新:

好的,做了一点研究。

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

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

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

Boost.TypeTraits 也没有任何匹配项 [再次强调,AFAICT]。

来自 Andrei Alexandrescu 的书:“Modern C++ Design: Generic Programming and Design Patterns Applied”,第 2.10 节类型特征:

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.

因此,如果您愿意,自己动手“没问题”。

但是,即使是他所说的 [来自 Loki] 的 TypeTraits,也没有任何与您正在做的相匹配的东西。

既然stdBoost都没有任何东西,那么问题就变成了“什么是标准?” [从你的角度]。某处可能有“fludger”c++ traits 库有一个实现,但那会被认为是“标准”吗? YMMV

但是,一两个问题:

为什么要这样做?它有什么用?基类中 protected typedef 怎么样?

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

所以,如果最后一个问题是真的,[IMO] 可能的答案是没有标准的方法来做到这一点,因为这不是一个应该的事情在标准库中执行。


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

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

所以,要么:

struct Foo

或者:

class Foo
{
    public:
    typedef int TD;
};

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

关于c++ - 检查类是否具有 typedef(私有(private)或其他)的特征,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34586624/

相关文章:

c++ - 如何使用 C++11 创建高效的闭包?

android - 使用Qt时如何在android中阻止后退键

c++ - 在 C++ : Why is a blank line entering getline after piping? 中编码管道 "|"

c++ - boost::bind thread 用于指向带参数的函数的指针

c++ - 为什么 ostream::write() 在 C++ 中需要 ‘const char_type*’ 而不是 ‘const void*’?

c++ - 如何确定一个参数是否是一个纯函数指针?

c++ - void function(...) 和 void 类型的 std::is_same?

c++ - 如何专门化 T 的特征类以及 T 的所有后代

c++ - 多级嵌套模板。我如何让它工作?

c++ - 使用 Detected Idiom 实现 is_destructible