有没有办法检查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
trait)有效,但所有POD类型只是所有类型的子集,支持此序列化。
所以我基本上有模板化函数write<T>
,它只写sizeof(T)
个字节(原始序列化)......但是我不想错误地调用它,我想要用户,明确地在他们的课堂上说:&#34;这个类/结构可以是原始序列化的#34;)。我这样做的方法是一个宏ALLOW_RAW_SERIALIZE
,它定义了一些可以通过trait检查的typedef。如果类MyClass
不包含typedef,则调用write(myClassInstance)
将产生编译器错误。
基本决定类是否可以原始序列化的事物是其成员(没有反射,成员不能自动枚举和检查,因此用户必须提供此类信息)。典型的类看起来像这样:
class
public
ctor-dtor
methods
private
methods
members
我希望用户允许写ALLOW_RAW_SERIALIZE
尽可能靠近成员,因此当他们更改某些成员时,忘记更新ALLOW_RAW_SERIALIZE
的机会就会更少(删除它。当它&# 39; s不再有效)
这就是我想检查private typedef
由于它可以替代反射并采用整体类型并编写它,所以我不会像打破封装那样堕落......
答案 0 :(得分:1)
<强>更新强>
好的,做了一点研究。
仅供参考,ideone
无法编译的[可能]原因是您正在做的事情需要-std=c++11
[或更高]。在添加之前我遇到了类似的错误。但是,我必须使用clang++
,g++
如果TD
为private
,则仍有问题需要编译。
但是,我不确定如果TD
是公开的,那么打印的唯一组合是真的。所有其他公共/私人以及TD
更改为TF
都会产生错误。也许VS2013工作[为什么?],但是其他两个编译器在编译或运行时结果中都有问题 - YMMV。
你所做的事情的基础是std::integral_constant
[自c ++ 11以来]。对于您正在做的事情,似乎没有标准的推导。也就是说,从http://www.cplusplus.com/reference/type_traits/integral_constant/开始,类型特征列表[在左侧]没有任何与您的用例[AFAICT]匹配的内容。
Boost.TypeTraits
也没有任何匹配[再次,AFAICT]。
来自Andrei Alexandrescu的书:&#34;现代C ++设计:应用的通用编程和设计模式&#34;,第2.10节类型特征:
通常,您将编写自己的特征模板和类,因为您的通用代码需要它们。但是,某些特征适用于任何类型。它们可以帮助通用程序员更好地定制模板代码以适应类型的功能。
所以,它可以&#34;好的&#34;如果你愿意,可以自己动手。
但是,即使他[来自Loki]的TypeTraits
再次提及的东西也没有与你正在做的事情相匹配。
由于std
和Boost
都没有任何内容,因此问题变为&#34;标准是什么?&#34; [从你的角度来看]。可能有&#34; fludger&#34; c ++ traits库在某个地方有一个实现,但是会被认为是&#34;标准&#34;? YMMV
然而,一两个问题:
为什么会这样做?有什么用?基类中受保护的typedef怎么样?
并且,这似乎需要了解课堂的私人部分,并且不会违反数据隐藏&#34;或封装[没有friend
某种声明]?
所以,如果最后一个问题属实,那么可能的[IMO]答案是没有标准的方法来做到这一点,因为它不是应该<的东西/ em>在标准库中做。
旁注:这是被投票的部分(在我真正理解这个问题之前)。我相信我已经在上面宣告自己无罪。所以,忽略下面的答案。
使用class
时,默认可见性为private
。使用struct
,它是public
。
所以,要么:
struct Foo
或者:
class Foo
{
public:
typedef int TD;
};
当然,这是假设您想要 TD
为public
答案 1 :(得分:0)
如果您只需要编译时检查,那么以下代码应该执行:
#include <iostream>
class Foo
{
typedef int TD;
template<typename T> friend class has_TD;
};
template <typename T>
struct has_TD
{
typedef typename T::TD type;
};
template <typename T, typename has_TD<T>::type = 0>
void write(const T& /*data*/)
{
std::cout << "serialize" << std::endl;
}
int main()
{
Foo foo;
write(foo);
}