首页 > 解决方案 > 在 C++ 模板中将变量作为参数传递

问题描述

我正在尝试实现以下函数调用:

template<int index>
void print() {
    std::cout << index;
}

constexpr int getConstexpr(int a) {
     return a;
}

void function_to_template(int i) {
    const int j = getConstexpr(i);
    print<j>();
}

void main() {
    for(int = 0 ; i < 10; i++) {
       function_to_template(i);
    }
}

我收到以下错误:

致命错误:没有匹配的成员函数调用“打印”。

我知道如何在 c++ 模板中将变量作为参数传递吗?

谢谢。

标签: c++c++11templatesconstexpr

解决方案


简短回答:您的代码不起作用,因为无法将运行时变量作为模板参数传递

长答案:问题是constexpr函数在可以(当输入知道编译时间时)和必须(当返回的值必须知道编译时间作为模板值或初始化constexpr值时)的情况下工作。编译器可以选择在不需要时计算值编译时间,但在不知道编译时间时无法编译。

所以你的constexpr功能

constexpr int getConstexpr(int a) {
     return a;
}

叫进来function_to_template()

void function_to_template(int i) {
    const int j = getConstexpr(i);
    print<j>();
}

是计算运行时(不是编译时),因为i是运行时值。

如果你想实现某种编译时间for,你应该使用标准模板工具来制作它(从 C++14 开始)或模拟它们(在 C++11 中)。我的意思是:std::make_integer_sequencestd::integer_sequence

以下是一个完整的编译示例,说明了我的意思

#include <utility>
#include <iostream>

template <int index>
void print ()
 { std::cout << index; }

template <int ... Is>
void foo (std::integer_sequence<int, Is...> const &)
 { 
   using unused = int[];

   (void)unused { 0, (print<Is>(), 0)... };
 }

int main ()
 {
   foo(std::make_integer_sequence<int, 10>{});
 }

从 C++17 开始可以使用模板折叠和简化foo(),避免丑陋的unused部分,如下

template <int ... Is>
void foo (std::integer_sequence<int, Is...> const &)
 { (print<Is>(), ...); }

推荐阅读