定义常量数组用作模板形参

Define constant array to use as template parameters

本文关键字:形参 常量 数组 定义      更新时间:2023-10-16

我正在寻找常量(n)的定义,允许它们在模板构造函数中用作参数,例如。像这样:

const int n[5] = { 4, 8, 16, 32, 64 };
for (int i = 0; i < 5; i++)
{
  SomeClass<n[i]> C;
  (...other things depending on n[i])
}

someeclass看起来像

template<int n> class SomeClass {...}

是否有任何方法(使用宏或其他任何东西)?

是的,您可以通过使用递归模板执行循环并将n指定为constexpr来做到这一点。这只适用于c++ 11或更高版本。工作示例(ideone link):

#include <type_traits>
template <int n> 
class SomeClass 
{
// debug function for example
public:
    void debug() {
        cout << "SomeClass<" << n << ">" << endl;
    }
};
constexpr int n[5] = { 4, 8, 16, 32, 64 };
template <int i>
struct loop
{
    static void doit()
    {
        SomeClass<n[i]> C;
        C.debug();
        // other things depending on n[i]
        loop<i+1>::doit();
    }
};
// close out the iteration
template <> 
struct loop<std::extent<decltype(n)>::value>
{    
    static void doit() 
    {
    } 
};
int main() {
    loop<0>::doit();
    return 0;
}
输出:

SomeClass<4>
SomeClass<8>
SomeClass<16>
SomeClass<32>
SomeClass<64>

这是不可能的for循环。原因很简单:循环中的n[i]不是一个常量表达式。i可以在循环中以不同的方式进行更改,并且有关是否实例化SomeClass的特定实例或其他实例的信息取决于运行时。

你可以使用模板元编程来代替:

template <int from, int to>
struct for_ {
    template<template<int> class Fn>
    static void run() {
        Fn<from>::run();
        for_<from + 1, to>::template run<Fn>();
    }
};
template <int to> 
struct for_<to, to> {  
    template<template<int> class Fn>
    static void run() {} 
};
然后,我们可以定义自己的实用程序:
template <int n> 
struct SomeClass {};
constexpr int n[5] = { 4, 8, 16, 32, 64 };
template<int i>
struct functor {
    static void run() {
        SomeClass<n[i]> c;
        // something else
    }
};

,并将其用作:

int main() {
    for_<0, 5>::run<functor>();
    return 0;
}

现场演示