我有自己的固定大小的数组类型,希望可以从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()
路线的情况下进行这项工作?
答案 0 :(得分:10)
您可以这样做:
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
成员函数。
答案 1 :(得分:8)
有没有一种方法可以在不遵循
make_array()
路线的情况下进行这项工作?
为什么不尝试使用以下推导指南?
template <typename T, std::size_t N>
array(T const (&)[N]) -> array<T, N>;
通过这种方式,myArray2 = {{1,2,3}}
中的参数不会被解释为std::initializer_list
(作为参数不能被视为constexpr
,因此size()
不能用作模板参数),但用作C样式数组。
因此可以推断出,作为模板参数,类型和大小(T
和N
)以及大小(N
)都可以用作模板参数。
答案 2 :(得分:2)
参数/参数值不是constexpr
。
您可以使用可变参数模板在编译时知道大小,或者使用已知大小(std::array
或C数组引用)进行键入。