c++ - 模板推导指南可以调用 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()
条路的情况下完成这项工作?
解决方案
你可以做:
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
推荐阅读
- c# - 生成没有特殊字符的唯一字符串
- vb.net - 无法将控件重命名为我删除的控件
- nosql - RavdnDb 自动索引
- javascript - 如何在组件中注入超过 1.5 倍的 Angular js 版本的服务?
- ios - 在从初始化程序返回之前,不会在所有路径上调用“super.init”
- python - Tensorflow:使用 argmax 对张量进行切片
- powershell - 如何使用 powershell 和 azure 函数创建 VM
- php - str_ireplace() 不只替换最后一个匹配
- sql-server - 如何在sqlserver中获取重复记录
- html - 删除内部的border-bottom nth-child