检查类是否具有 typedef(私有或其他)的特征
Trait which checks whether class has typedef (private or other) or not
有没有办法检查class
是否有甚至适用于private
typedef
的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;
}
编辑 - 为什么我想要这个
我有自定义序列化系统,可以序列化任意类型。当它的行为必须不同时,它有几个重载(例如字符串(。对于其余类型,它只是将值写入内存。如果我有组合类型,我有时也可以写入内存(保存和加载发生在相同的架构上,使用相同的编译器编译,因此填充将是相同的,等等(。例如,此方法对 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
我希望用户允许写ALLOW_RAW_SERIALIZE
尽可能接近成员,所以当他们更改某些成员时,忘记更新ALLOW_RAW_SERIALIZE
的机会较小(当它不再有效时将其删除(
所以这就是为什么我想检查一个private typedef
由于它是反射的替代品,并且采用整个类型并编写它,因此我不会像打破封装之类的那样陷入困境......
更新:
好的,做了一些研究。
仅供参考,ideone
没有编译的[可能]原因是您正在做的事情需要-std=c++11
[或更高]。 在添加之前,我遇到了类似的错误。 但是,我不得不使用clang++
因为如果TD
g++
编译时仍然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的书:"现代C++设计:通用编程和设计模式应用",第2.10节类型特征:
通常,您将编写自己的特征模板和类,因为您的通用代码需要它们。但是,某些特征适用于任何类型。它们可以帮助泛型程序员更好地定制模板代码以适应类型的功能。
因此,如果您愿意,可以自己滚动
。但是,即使是他(来自洛基(谈论的TypeTraits
,也没有任何东西与你正在做的事情相匹配。
既然std
和Boost
都没有任何东西,那么问题就变成了"什么是标准?[从你的角度来看]。 可能在某个地方有"fludger"c++ 特征库有一个实现,但这会被认为是"标准"吗? 扬子晚报
但是,一两个问题:
为什么要这样做? 它有什么用? 基类中受保护的类型定义呢?
而且,这似乎需要了解类的私有部分,这难道不是违反"数据隐藏"或封装[没有某种friend
声明]吗?
因此,如果最后一个问题是真的,那么可能的答案是没有标准的方法可以做到这一点,因为这不是标准库中应该做的事情。
旁注:这是被否决的部分(在我[真正]理解这个问题之前(。 我相信我已经在上面无罪释放了自己。 所以,忽略下面的答案。
使用class
时,默认可见性为 private
。 有了struct
,就public
了。
因此,要么执行以下操作:
struct Foo
或:
class Foo
{
public:
typedef int TD;
};
当然,这是假设您希望TD
public
如果您只需要编译时检查,那么以下代码应该可以:
#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);
}
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- GL_SHADERSTORAGE_BUFFER位置是否与其他着色器位置冲突
- 为什么我不能在 C++ 中的特定函数重载中调用同一函数的任何其他重载?
- 在其他文件中创建类时在 c++ 项目中不起作用
- 类与私有变量的其他类之间的线程安全性
- 特征::矩阵<双精度,1,3> 结构类型函数中的返回类型函数
- 将--whole archive链接器选项与CMake和具有其他库依赖项的库一起使用
- 有没有一种方法可以通过"typedef"为重新定义的基本类型定义特征和强制转换运算符
- GlobalAlloc而不是其他分配方法
- C++从其他 constexpr 创建 lambda 不能按顺序执行 Constexpr
- 断言中的Fold表达式在某些计算机上编译,但在其他计算机上不编译
- 特征命名访问向量段
- 将特征矩阵的向量设置为0
- Visual Studio(或任何其他工具)能否将地址解释为调用堆栈(boost上下文)的开头
- 是否有类型特征显示一种类型是否可能包含其他类型的值
- 是否有等效于其他语言中C++的类型特征
- 检查类是否具有 typedef(私有或其他)的特征