C++模板:根据模板参数的值选择不同的类型

por*_*uod 13 c++ templates

我如何在C++中完成以下任务,以及这样做的事情是什么?

template <bool S>
class NuclearPowerplantControllerFactoryProviderFactory {
  // if S == true
  typedef int data_t;
  // if S == false
  typedef unsigned int data_t;
};
Run Code Online (Sandbox Code Playgroud)

Ker*_* SB 17

通过专业化:

template <bool> class Foo;

template <> class Foo<true>
{
  typedef int data_t;
};

template <> class Foo<false>
{
  typedef unsigned int data_t;
};
Run Code Online (Sandbox Code Playgroud)

您可以选择将两种情况中的一种作为主要模板,另一种作为特殊化,但我更喜欢这种更对称的版本,因为它bool只能有两个值.


如果这是您第一次看到这个,您可能还想考虑部分专业化:

template <typename T> struct remove_pointer     { typedef T type; };
template <typename U> struct remove_pointer<U*> { typedef U type; };
Run Code Online (Sandbox Code Playgroud)


正如@Nawaz所说,最简单的方法可能是#include <type_traits>:

typedef typename std::conditional<S, int, unsigned int>::type data_t;
Run Code Online (Sandbox Code Playgroud)

  • 每次我学习新的C++语法时,我写的所有未来代码的可读性都会受到影响...... (4认同)
  • @porgarmingduod:恰恰相反!看看我在更新后的帖子中的最后一行:一行,它完全是自我描述的。如果您使用正确的工具和构建块,您的代码实际上会变得*更*可读且不那么冗长。你可以用自我描述的俏皮话代替不透明的语法废话。 (2认同)

Naw*_*waz 7

@Kerrek已经充分回答了这个问题,但这可以更通用如下:

template<bool b, typename T, typename U>
struct select
{
    typedef T type;
};
template<typename T, typename U>
struct select<false, T, U>
{
    typedef U type;
};
Run Code Online (Sandbox Code Playgroud)

用作:

template <bool S>
class NuclearPowerplantControllerFactoryProviderFactory 
{
  typedef typename select<S, int, unsigned int>::type data_t;
  //use data_t as data type
};
Run Code Online (Sandbox Code Playgroud)

如果S为true,select将选择第一个类型参数,否则将选择第二个类型参数.它是通用的,因为您指定了两种类型select<>,并且基于布尔值,select<b,T,U>::type返回第一种类型或第二种类型.

  • 这也称为`std :: conditional` :-) (12认同)
  • @porgarmingduod:黄金法则是您应该*了解*如何使用模板专门化来做出编译时决策,然后*然后*您查看`&lt;type_trait&gt;`库并查看已经存在的所有精彩工具专为您使用:-) (2认同)