如何在模板元编程中使用'default'值
How to use 'default' value within template metaprogramming
我面临以下问题:
我有一些通用容器,能够对类型进行一些操作。为简单起见,这些操作在请求时是线程安全的。并且,请求 to表示容器中的类型具有typedef std::true_type needs_thread_safety;
.
struct thread_safe_item {
typedef std::true_type needs_thread_safety;
/* */
};
struct thread_unsafe_item {
typedef std::false_type needs_thread_safety;
/* */
};
template<typename TItem> container {
/* some algorithms, that are std::enable_if selected, according to needs_thread_safety */
};
但是,我希望选择加入needs_thread_safety
,并且不需要定义(= 默认false_type)。我尝试了以下方法:
struct thread_unsafe_item {
/* */
};
template<typename TItem>
struct thread_safety_selector
{
template<typename T>
struct has_defined_thread_safety
{
typedef char yes[1];
typedef char no[2];
template <typename C> static yes& test(typename C::needs_thread_safety*);
template <typename> static no& test(...);
static const bool value = sizeof(test<T>(0)) == sizeof(yes);
};
typedef
typename std::conditional<
has_defined_thread_safety<TItem>::value,
typename TItem::needs_thread_safety,
std::false_type
>::type needs_thread_safety;
};
....
struct <typename TItem> container {
/* changed all TItem::needs_thread_safety selectors to thread_safety_selector<TItem>::needs_thread_safety */
};
但是显然没有进行惰性评估,因为错误error C2039: 'needs_thread_safety' : is not a member of 'thread_unsafe_item'
。
如何实现未指定参数的默认值?
这是出于教育目的,所以我不需要不同的方法来解决这个问题。
谢谢!
您不能为此使用std::conditional
,因为这将始终解析其所有参数。您可以创建自己的谓词:
template <bool, class>
struct get_thread_safety;
template <class T>
struct get_thread_safety<true, T>
{
typedef typename T::needs_thread_safety type;
};
template <class T>
struct get_thread_safety<false, T>
{
typedef std::false_type type;
};
// Used like this:
typedef
typename get_thread_safety<
has_defined_thread_safety<TItem>::value,
TItem
>::type needs_thread_safety;
实际上,使用std::enable_if
与std::conditional
结合使用可以更轻松地完成此操作:
#include <iostream>
#include <type_traits>
// Classes to be checked against needs_thread_safety
struct A {};
struct B { typedef std::true_type needs_thread_safety; };
struct C { typedef std::false_type needs_thread_safety; };
// Checker helper
template<class T> class get_thread_safety
{
typedef char(&zero_size_t)[0];
template <class X> static typename std::enable_if<X::needs_thread_safety::value, char>::type check(int);
template <class X> static typename std::enable_if<!X::needs_thread_safety::value, zero_size_t>::type check(int);
template <class X> static zero_size_t check(...);
public:
typedef typename std::conditional<sizeof(check<T>(0)), std::true_type, std::false_type>::type type;
};
int main()
{
// Usage. Will print 0 1 0
std::cout << get_thread_safety<A>::type::value << std::endl;
std::cout << get_thread_safety<B>::type::value << std::endl;
std::cout << get_thread_safety<C>::type::value << std::endl;
return 0;
}
您实际上可以懒惰地使用std::conditional
,您只需要避免在其模板参数列表中使用嵌套的 typedef。对于false
情况,您还需要另一种回退类型(您称之为"默认值"):
template<typename TItem>
struct thread_safety_selector
{
template<typename T>
struct has_defined_thread_safety
{
typedef char yes[1];
typedef char no[2];
template <typename C> static yes& test(typename C::needs_thread_safety*);
template <typename> static no& test(...);
static const bool value = sizeof(test<T>(0)) == sizeof(yes);
};
// this would be your "default value"
struct not_thread_safe {
typedef std::false_type needs_thread_safety;
};
typedef
typename std::conditional<
has_defined_thread_safety<TItem>::value,
TItem, // <---- note, not using the typedef here
not_thread_safe
>::type::needs_thread_safety needs_thread_safety;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^
// lazily, after the selection is done
};
相关文章:
- 在提升multi_index容器中,是否定义了"default index"?
- 有一个打印语句的函数是一种糟糕的编程实践吗
- 我是C++编程的新手,这些代码之间有什么区别,我应该使用哪一个
- 模板元编程:如何将参数包组合成新的参数包
- Qt Q串行端口未编程设备未关闭
- 模板元编程 - 尝试实现维度分析
- 我是编程新手
- C++编程从外部文本文件定义数组大小
- 了解算法的性能差异(如果以不同的编程语言实现)
- 使用 Gtkmm 以编程方式选择 Gtk::TextView 中的文本
- 如何将可变参数模板转换为多个单个模板?(C++竞争编程调试模板)
- 用"=default"声明的函数应该只在头文件中执行
- 使用命名空间正确编程
- C++编程:运算符重载中的引用如何工作?
- Arduino 模块化编程与全局和设置
- C++ 运算符修改/元编程策略,用于不那么冗长的语法
- 在没有管理员权限的情况下,在 c++ 中以编程方式将程序添加到启动
- 如何以编程方式将音频从任何录制设备路由到任何播放设备
- 试图修复一个错误,该错误不会让我开始编程其余部分
- 如何在模板元编程中使用'default'值