首页 > 解决方案 > 模板推导指南可以调用 constexpr 函数吗?

问题描述

我有我自己的固定大小的数组类型,我希望可以constexpr从一个构造,std::initializer_list而不必显式定义大小模板参数。

我以为我可以使用模板推导指南,但看起来它没有std::initializer_list::size()被视为 constexpr 函数。

这是一个尝试为std::array(与我的类型相似并且有同样的问题)制作演绎指南的示例:

namespace std
{
    template<typename T> array(initializer_list<T> initialiserList) -> array<T, initialiserList.size()>;
}
static constexpr std::array myArray = {1,2,3};
static constexpr std::array myArray2 = {{1,2,3}};

我在 MSVC 和 Clang 上试过,都给出了大致相同的错误: myArray有一个错误,抱怨函数参数太多。 myArray2说“替换失败 [with T = int]:非类型模板参数不是常量表达式”

我尝试将constexpr演绎指南或函数参数放在前面,但似乎都不允许,因此即使在constexpr上下文中应该可以正常工作,演绎指南似乎也是无效的。

有没有办法在不走这make_array()条路的情况下完成这项工作?

标签: c++c++17constexprtemplate-argument-deduction

解决方案


你可以做:

template <class T, class... U>
array(T, U...) -> array<T, 1 + sizeof...(U)>;

问题不在于您不能constexpr在演绎指南中调用函数。你可以。这个例子很荒谬,但有效:

constexpr size_t plus_one(size_t i) { return i + 1; }

template <class T, class... U>
array(T, U...) -> array<T, plus_one(sizeof...(U))>;

问题是函数参数不是对象,因此如果这些成员函数读取某种本地状态,constexpr则无法在它们上调用成员函数。constexpr


推荐阅读