有没有办法检查是否class有typedef哪个有效private typedef?
以下代码适用于VS2013,但在ideone的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;
}
Run Code Online (Sandbox Code Playgroud)
编辑 - 为什么我想要这个
我有自定义序列化系统,可以序列化任意类型.当它必须表现不同时(例如字符串),它有几个重载.对于其余类型,它只是将值写入内存中.如果我有编写类型,我有时也可以写入内存(保存和加载发生在同一架构上,使用相同的编译器编译,因此填充将是相同的,等等).此方法对于POD类型(std::is_pod特征)有效,但所有POD类型仅是所有类型的子集,支持此序列化.
所以我基本上都有模板化的函数write<T>,它只是写sizeof(T)字节(原始序列化)...但是我不希望这个被错误地调用,我想要用户,在他们的类中明确地说:"这个类/结构可以是原始的序列化过").我这样做的方法是ALLOW_RAW_SERIALIZE定义一些可以通过trait检查的typedef 的宏.如果类MyClass不包含typedef,则调用write(myClassInstance)将产生编译器错误.
基本决定类是否可以原始序列化的东西是它的成员(没有反射,成员不能自动枚举和检查,因此用户必须提供这样的信息).典型的类看起来像这样:
class
public
ctor-dtor
methods
private
methods
members
Run Code Online (Sandbox Code Playgroud)
我希望用户允许写入ALLOW_RAW_SERIALIZE尽可能接近成员,所以当他们更改某些成员时,忘记更新的可能性较小ALLOW_RAW_SERIALIZE(删除它.当它不再有效时)
所以这就是我想检查的原因 private typedef
因为它可以代替反射并采用整体类型并编写它,所以我不会像打破封装那样堕落......
更新:
好吧,做了一点研究。
仅供参考,未编译的[可能]原因ideone是您正在做的事情需要-std=c++11[或更高]。在添加之前我遇到了类似的错误。但是,我不得不使用clang++asg++编译时仍然存在问题 if TDwas private。
但是,我不确定这是否有效,因为唯一打印正确的组合是TD公开的。所有其他公共/私人和更改TD都TF产生了错误。也许 VS2013 可以工作[为什么?],但是另外两个编译器在编译或运行时结果方面都有问题——YMMV。
你正在做的事情的基础是std::integral_constant[since c++11]。对于您正在做的事情似乎没有标准的推导。也就是说,来自http://www.cplusplus.com/reference/type_traits/integral_constant/的类型特征列表[左侧]没有任何与您的用例匹配的内容[AFAICT]。
也没有Boost.TypeTraits任何匹配的东西[再次,AFAICT]。
来自 Andrei Alexandrescu 的书:“现代 C++ 设计:通用编程和应用的设计模式”,第 2.10 节类型特征:
通常,您将根据通用代码的需要编写自己的特征模板和类。然而,某些特征适用于任何类型。它们可以帮助通用程序员更好地定制模板代码以适应类型的功能。
因此,如果您愿意,可以自己推出。
但是,即使是TypeTraits他[从洛基那里]谈到的,也没有任何与你正在做的事情相匹配的东西。
既然既不是std也不是Boost没有,那么问题就变成了“什么是标准?” [从你的角度来看]。某个地方可能有一个具有实现的“fludger”c++ 特征库,但这会被认为是“标准”吗?青年MMV
不过,有一两个问题:
为什么要这样做呢?它有什么用呢?基类中受保护的 typedef 怎么样?
而且,这似乎需要了解类的私有部分,这是否会违反“数据隐藏”或封装[没有friend某种声明]?
因此,如果最后一个问题是正确的,那么 [IMO] 可能的答案是没有标准方法可以做到这一点,因为这不是人们应该在标准库中做的事情。
边注:这是被否决的部分(在我[真正]理解这个问题之前)。我相信我已经在上面无罪释放了。所以,请忽略下面的答案。
当您使用class默认可见性时private。与struct,它是public。
所以,要么这样做:
struct Foo
Run Code Online (Sandbox Code Playgroud)
或者:
class Foo
{
public:
typedef int TD;
};
Run Code Online (Sandbox Code Playgroud)
当然,这是假设您想 TD成为public