在模板参数中使用静态constexpr成员数组作为指针。

问题描述 投票:2回答:1

下面的main.cpp说明了这个问题。

#include <type_traits>

template <class T, std::size_t N>
struct Array
{
    T data_[N];
};

template <const std::size_t* EltArray, std::size_t EltCount>
struct Foo
{

};

int main()
{
    // SIDE NOTE if arr is not declared static: the address of 'arr' is not a valid template argument
    // because it does not have static storage duration
    static constexpr std::size_t arr[3] = {1, 2, 3};
    Foo<arr, 3> foo;// WORKING

    static constexpr Array<std::size_t, 3> arr2 = {1, 2, 3};
    static constexpr const std::size_t* arr2_ptr = arr2.data_;
    Foo<arr2_ptr, 3> foo2;// ERROR:
    // 'arr2_ptr' is not a valid template argument of type 'const size_t*'
    // {aka 'const long long unsigned int*'} because
    // 'arr2.Array<long long unsigned int, 3>::data_' is not a variable

    static constexpr const std::size_t* test = std::integral_constant<const std::size_t*, arr2_ptr>{};// ERROR:
    // 'arr2_ptr' is not a valid template argument of type 'const long long unsigned int*' because
    // 'arr2.Array<long long unsigned int, 3>::data_' is not a variable

    return 0;
}

我不明白为什么arr2.data_不能像arr一样重用. 谁能解释一下?

我使用的是gcc: mingw-w64\x86_64-8.1.0-posix-sjlj-rt_v6-rev0。

g++.exe -Wall -std=c++2a -fconcepts -O2

c++ templates static constexpr non-type
1个回答
0
投票

我想分享 回答 我只是在open-std中找到了一个符合标准的东西 解决办法.

我们都知道,我们不能传递任何非类型的变量。

你知道我们可以传递一个const引用给任何我们想要的东西吗?

所以 解决办法 是。

#include <array>

// When passing std::array<std::size_t, EltCount> (by value), i get the error:
// 'struct std::array<long long unsigned int, EltCount>' is not a valid type for a template non-type parameter

template <std::size_t EltCount, const std::array<std::size_t, EltCount>& Elts>
struct Foo {};

static constexpr std::array<std::size_t, 3> arr = {1, 2, 3};

int main()
{
    Foo<3, arr> foo;// WORKING

    return 0;
}

还有... 回答 对最初的问题是。

引用N4296号文件

14.3.2 模板非类型参数[temp.arg.nontype]

对于引用或指针类型的非类型模板参数,常量表达式的值不得引用(或对于指针类型,不得是地址):(1.1)-子对象(1.8)。

故事的寓意注意:我们可以用引用来做我们想做的事情,而不是用指针。

© www.soinside.com 2019 - 2024. All rights reserved.