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

标签 c++ c++17 constexpr template-argument-deduction

我有自己的固定大小的数组类型,我希望 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++ - 模板推导指南可以调用 constexpr 函数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54066651/

相关文章:

c++ - 右值引用到左值引用 - ub?

c++ - 函数模板重载解析,依赖和非依赖参数

c++ - 如何在编译时初始化一个 float 组?

c++ - std::abs 可以在 constexpr 函数中使用,但前提是它是模板化的。为什么?

c++ - constexpr 类的设计 : merging constexpr and non-constexpr versions?

c++ - 声明 `const` `boost::range` s 的正确方法

c++ - C++中的结构指针

c++ - 是否可以使用 googletest 在基类中定义(纯虚拟)测试用例

c++ - 如何在重命名函数(c++)中使用变量?

c++ - 为什么 is_integral 认为 std::string 是整数?