模板扣除指南可以调用constexpr函数吗?

Bla*_*ton 14 c++ constexpr template-argument-deduction c++17

我有自己的固定大小数组类型我希望可以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}};
Run Code Online (Sandbox Code Playgroud)

我已经尝试了MSVC和Clang,两者都给出了大致相同的错误: myArray有一个错误抱怨该函数的参数太多. myArray2说"替换失败[使用T = int]:非类型模板参数不是常量表达式"

我试图把constexpr在扣除指南或函数参数的前面,但它们似乎也没有被允许,所以看来扣除指南是无效的,即使它应该在正常工作constexpr范围内.

有没有办法让这项工作不走这make_array()条路?

Bar*_*rry 10

你可以做:

template <class T, class... U>
array(T, U...) -> array<T, 1 + sizeof...(U)>;
Run Code Online (Sandbox Code Playgroud)

问题不在于您无法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))>;
Run Code Online (Sandbox Code Playgroud)

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


max*_*x66 8

有没有办法让这项工作不走这make_array()条路?

为什么不尝试使用以下演绎指南?

template <typename T, std::size_t N>
array(T const (&)[N]) -> array<T, N>;
Run Code Online (Sandbox Code Playgroud)

这样,参数in myArray2 = {{1,2,3}}不会被解释为std::initializer_list(因为参数不能被考虑constexpr,所以它size()不能用于模板参数)而是被解释为C风格的数组.

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