根据模板参数内容执行或跳过代码
Execute or skip code based on template parameter contents
我想为任意类型 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
实例必须具有名称header
my_header
的实例是类 T 中的第一个成员变量- 类 T 派生自 my_header 而不是将其作为成员变量包含在 内
使用 C++11 很好(实际上是预期的)。
不是最好的解决方案,但我认为它可以工作。从 如何检测类中是否存在特定成员变量?
#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.
}
remyable 的解决方案还不错(+1),但可以简化:
#include <iostream>
#include <type_traits>
struct my_header {
int time = 0;
};
template<typename T>
using has_header = std::is_same< decltype( T::header ), my_header >;
struct foo
{
my_header header;
};
template<typename T, typename = void>
class my_container
{
public:
T val;
void foo()
{
std::cout << "other.n";
}
};
template<typename T>
class my_container<T, typename std::enable_if<has_header<T>::value>::type>
{
public:
T val;
void foo()
{
std::cout << "time: " << val.header.time << "n";
}
};
int main()
{
my_container<foo> c;
my_container<int> c2;
c.foo(); // time: 0
c2.foo(); // other.
}
现场示例
当然,此解决方案仍然使用调用成员变量的要求,header
C++没有可以迭代类型成员的内省。
相关文章:
- 需要将此代码更改为执行代码
- 当前不会命中断点。没有调试器目标代码类型的可执行代码与此文件关联
- 单步执行代码时重复上一行
- 如何使用介子在C++中执行代码覆盖?
- Visual Studio 2017,C++,在单步执行代码时指向错误的行
- 在 R 中执行C++代码
- 通过 dll 注入在主线程中执行代码
- 无法在 c++ 中循环后执行代码
- 执行C 代码时快速频繁的文件访问
- 执行 C++ 代码后出错
- 一个人如何从代表函数的字符串中执行运行时执行C 代码
- 是否可以在程序崩溃后执行代码?
- 第一次在 Linux 上执行 c++ 代码的时间非常慢
- 计算 JSON 中的条目数并相应地执行代码
- 将在 CATCH 块之后执行代码
- 分析执行C++代码的每一行所花费的确切时间
- 我在执行代码时不断得到"Bus Error"?
- c while()..执行代码行的条件
- 从并行线程在主 Maya 线程上执行代码
- 在调用GNUPLOT之后,如何继续执行C 代码