template<unsigned int size>
struct Vec {
Vec() = default;
};
auto build_vec(unsigned int size) {
return Vec<size>();
}
int main() {
auto vec = build_vec(5);
return 0;
}
这个程序不能编译为 non-type template argument is not a constant expression
。基本上,编译类型期间编译器不知道发送到 size
的 build_vec
参数。
那么我想知道,我可以添加一些关键字来强制在编译时评估 size
从而可以通过函数构建 struct Vec
吗?
答案 0 :(得分:1)
不,这是不可能的。函数参数在编译时未知。表示 size
必须在编译时已知的常用方法是将函数设为模板,将 size
设为模板参数:
template<unsigned int size>
struct Vec {
Vec() = default;
};
template <unsigned int size>
auto build_vec() {
return Vec<size>();
}
int main() {
auto vec = build_vec<5>();
}
不过,现在应该很明显该函数并不能帮助将运行时值转换为编译时值。通常这是不可能的,除非您手动实现此类映射。您不需要 build_vec
,因为调用者可以直接使用 auto vec = Vec<size>();
。
答案 1 :(得分:1)
它不完全符合您的期望,但依赖于我们可能有类似的 boost hana 方法。下面是一个使用变量模板的例子
#include <iostream>
template<unsigned int size>
struct Vec {
Vec() = default;
~Vec() {std::cout << size << '\n';}
};
template <unsigned int i>
constexpr std::integral_constant<unsigned int, i> uint_c{};
template <unsigned int i>
auto build_vec(std::integral_constant<unsigned int, i>) {
return Vec<i>();
}
int main() {
const size_t n = 5;
auto vec = build_vec(uint_c<n>);
return 0;
}
答案 2 :(得分:0)
我的代码库限制我它必须是函数参数,而不是模板参数。
这不可能。函数的返回类型不能依赖于运行时值。您的选择是:
Vec
的模板参数设为运行时值。std::any
等),让 Vec
类派生自某个基类,或者不返回该对象。如果范围太大,请不要这样做。它可能generate大量代码膨胀:#include <cstdio>
#include <utility>
template <unsigned size>
struct Vec {
Vec() = default;
void use_value() { std::printf("My constexpr value is %u\n", size); }
};
template <unsigned ct_val>
void build_vec_impl_impl() {
Vec<ct_val> cant_return;
cant_return.use_value();
}
template <unsigned... vals>
void build_vec_impl(std::integer_sequence<unsigned, vals...>, unsigned rt_val) {
using fp_builder = void (*)();
constexpr fp_builder builders[]{build_vec_impl_impl<vals>...};
builders[rt_val]();
}
template <unsigned max>
void build_vec(unsigned const rt_val) {
using seq = std::make_integer_sequence<unsigned, max + 1>;
build_vec_impl(seq{}, rt_val);
}
int main() {
auto constexpr max = 10;
for (unsigned i = 0; i < max; ++i) build_vec<max>(i);
}
3.使用像 Python 这样的动态语言,其中返回类型可能取决于运行时值