C++ 如何使用';默认值';模板元编程中的值

C++ 如何使用';默认值';模板元编程中的值,c++,templates,c++11,metaprogramming,C++,Templates,C++11,Metaprogramming,我面临以下问题: 我有一些通用容器,可以对类型执行一些操作。为简单起见,这些操作在被请求时是线程安全的。并且,请求表示容器中的类型具有typedef std::true\u type需要线程安全性 struct thread_safe_item { typedef std::true_type needs_thread_safety; /* */ }; struct thread_unsafe_item { typedef std::false_type needs_

我面临以下问题:

我有一些通用容器,可以对类型执行一些操作。为简单起见,这些操作在被请求时是线程安全的。并且,请求表示容器中的类型具有
typedef std::true\u type需要线程安全性

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 */
};
但显然没有进行延迟评估,因为错误是
错误C2039:“需要线程安全”:不是“线程不安全项目”的成员。

如何获得未指定参数的默认值

这是为了教育目的,所以我不需要不同的方法来解决这个问题


谢谢

您不能为此使用
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;
模板
结构获得线程安全;
模板
结构获取线程安全
{
typedef typename T::需要线程安全类型;
};
模板
结构获取线程安全
{
typedef std::false_type类型;
};
//这样使用:
类型定义
typename获取线程安全<
已定义线程安全::值,
滴度
>::类型需要线程安全性;

实际上,如果将
std::enable\u与
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;
}
#包括
#包括
//要根据需要检查的类\u线程\u安全
结构A{};
结构B{typedef std::true_type需要_thread_safety;};
结构C{typedef std::false_type需要_thread_safety;};
//棋盘格助手
模板类获取线程安全
{
typedef char(&zero_size_t)[0];
模板静态typename std::enable_if::type check(int);
模板静态typename std::enable_if::type check(int);
模板静态零尺寸检查(…);
公众:
typedef typename std::conditional::type type;
};
int main()
{
//用法。将打印0 1 0

std::cout实际上,您可以懒洋洋地使用
std::conditional
,您只需要避免在其模板参数列表中使用嵌套的typedef。对于
false
案例(“默认值”),您还需要另一种回退类型:

模板
结构线程\安全\选择器
{
模板
结构已定义线程安全
{
typedef char yes[1];
typedef字符编号[2];
模板静态是&测试(类型名C::需要线程安全*);
模板静态无测试(…);
静态常量布尔值=sizeof(测试(0))==sizeof(是);
};
//这将是您的“默认值”
结构不是线程安全的{
typedef std::false_类型需要线程安全;
};
类型定义
类型名称std::条件<
已定义线程安全::值,
TItem,/::类型::需要线程安全需要线程安全;
//  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
//懒洋洋地,在选择完成之后
};

通常我使用类型选择器来指定最终类的特定基类,其中基类包含适当的实现。+1,但也可以使用
std::conditional
。而不是
yes
no
(以及
sizeof
),您可以使用
std::true_type
std::false_type
作为返回类型(然后,
decltype(test(0))::value
(如果需要)。
#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;
}
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
};