模板推导指南可以调用 constexpr 函数吗?

Can template deduction guides call constexpr functions?

我有自己的固定大小的数组类型,我想 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 说 "substitution failure [with T = int]: non-type template argument is not a constant expression"

我尝试将 constexpr 放在推导指南或函数参数的前面,但似乎都不允许,因此推导指南似乎无效,即使它在 [=11] 中应该可以正常工作=]上下文。

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

Parameter/argument 值不是 constexpr.

您可以使用可变参数模板在编译时知道大小,或者键入已知大小(std::array 或 C 数组引用)。

Is there a way to make this work without going down the make_array() route?

你为什么不试试下面的推导指南?

template <typename T, std::size_t N>
array(T const (&)[N]) -> array<T, N>;

这样,myArray2 = {{1,2,3}} 中的参数不会被解释为 std::initializer_list(因为参数不能被视为 constexpr,所以它是 size() 't 用于模板参数)但作为 C 样式数组。

因此可以推断,作为模板参数,类型和大小(TN)以及大小(N)都可以用作模板参数。

你可以这样做:

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 成员函数。