我想为任意类型T创建一个容器.但是,如果T有一个头类型的成员(我也定义),我想添加一些功能.如果T没有该标头成员,则可以跳过添加的功能.
例如,添加的功能可以是基于何时执行操作来添加时间戳.这是我想要的伪代码:
struct my_header {
timestamp_t time;
// ... etc ...
}
template <class T>
class my_container {
public:
void some_operation(T val) {
// condition evaluated at compile time
if T has a member of type my_header {
val.header.time = get_current_time();
// ... etc ...
}
// other operations, agnostic to T
}
};
当然,正如我所知,some_operation还必须找出类T中my_header实例的名称.可以通过对要使用的附加功能强加以下要求之一来消除此要求(按从大多数到最小的顺序)优选):
>类T中的my_header实例必须具有名称标题
> my_header的实例是T类中的第一个成员变量
> class T派生自my_header而不是将其包含为成员变量
使用C 11很好(实际上是预期的).
最佳答案 不是最好的解决方案,但我认为它可以工作.来自
How to detect whether there is a specific member variable in class?的被盗代码
#include <iostream>
#include <type_traits>
struct my_header {
int time;
};
// begin stolen code
template<typename T, typename V = bool>
struct has_header : std::false_type { };
template<typename T>
struct has_header<T,
typename std::enable_if<
!std::is_same<decltype(std::declval<T>().header), void>::value,
bool
>::type
> : std::true_type { };
// end stolen code
struct foo
{
my_header header;
};
template<typename, typename = void>
class my_container;
template<typename T>
class my_container<T, typename std::enable_if<has_header<T>::value>::type>
{
public:
T val;
void foo()
{
std::cout << val.header.time << "\n";
}
};
template <typename T>
class my_container<T, typename std::enable_if<!has_header<T>::value>::type>
{
public:
T val;
void foo()
{
std::cout << "other.\n";
}
};
int main()
{
my_container<foo> c;
my_container<int> c2;
c.foo(); // garbage
c2.foo(); // other.
}