【问题标题】:Define constant array to use as template parameters定义常量数组以用作模板参数
【发布时间】:2015-09-13 16:57:48
【问题描述】:

我正在寻找常量 (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])
}

SomeClass 看起来像

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

有什么办法(使用宏或其他方法)吗?

【问题讨论】:

    标签: c++ arrays templates constants


    【解决方案1】:

    是的,您可以使用递归模板进行循环并将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>
    

    【讨论】:

    • 我认为它也适用于 C++11(在 Clang 和 GCC 上都试过)。
    • @REACHUS:谢谢,我自己也在 gcc 中尝试过,它成功了 - 更新了我的答案。
    【解决方案2】:

    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;
    }
    

    Live demo

    【讨论】:

    • 问题的重点是“我如何使n[i] 保持不变”。因此,“您需要使n[i] 保持不变”的答案没有用处。
    • @LightnessRacesinOrbit Ow。很抱歉你不喜欢这个答案。 :(
    • 这是一种更好的 for 循环方式!
    猜你喜欢
    • 2020-12-17
    • 1970-01-01
    • 2019-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多