开发者问题收集

将数组元素传递给模板

2020-10-28
597

我认为下面的代码是不言自明的。我可以轻松地将静态变量传递给模板参数,并且它会按预期工作。使用静态数组将清理代码,因此看起来更好,但不幸的是,由于我在注释中粘贴的错误,它无法编译。请注意,它是使用 c++17 标志由 gcc 10.2 编译的。 所以问题是如何将数组元素传递给模板。

#include <iostream>
#include <vector>
#include <tuple>

using DataTransfer = std::tuple<char, int>;
using DataPool     = std::vector<DataTransfer>;

typedef struct Event
{
    DataPool dataPool;
    const char* description;
} Event;

template <Event& event>
class EventTransmitter
{
    public:
    EventTransmitter()
    {
        std::cout<<event.description<<"\n";
    }
};

static Event ev1{ {{'d', 4}, {'a', 1}}, "Description 1"};
static Event ev2{ {{'g', 7}, {'b', 6}}, "Description 2"};

static Event evs[2] {
    { {{'d', 4}, {'a', 1}}, "Description 1"},
    { {{'g', 7}, {'b', 6}}, "Description 2"}
};

int main()
{
    EventTransmitter<ev1> e1;
    EventTransmitter<ev2> e2;
    
    //EventTransmitter<evs[0]> e3;
    //error: '& evs[0]' is not a valid template argument of
    //type 'Event&' because 'evs[0]' is not a variable
    return 0;
}  
2个回答

TL;DR 升级你的编译器,并希望它们完全实现 C++20。


这个问题纯粹是关于非类型模板参数的

template<int&>
struct S;

static int i;
static int arr[42];

S<i> s1;
S<arr[0]> s2;  // ill-formed?

如果你想知道的话, static 也是无关紧要的。

这条规则存在于 C++17 [temp.arg.nontype]

For a non-type template-parameter of reference or pointer type, the value of the constant expression shall not refer to (or for a pointer type, shall not be the address of):

  • a subobject, [...]

这在 C++20

For a non-type template-parameter of reference or pointer type, [...] the reference or pointer value shall not refer to or be the address of (respectively):

  • a temporary object,
  • a string literal object,
  • the result of a typeid expression,
  • a predefined __func__ variable, or
  • a subobject of one of the above.

至于原因,我只能假设标准谨慎地仅要求非常小的子集值,以避免无法实现的可能性。

Passer By
2020-10-28

这里有一个答案(已被删除)给了我一个解决该问题的方法。它并不完美,但也不错。

#include <iostream>
#include <vector>
#include <tuple>

using DataTransfer = std::tuple<char, int>;
using DataPool     = std::vector<DataTransfer>;

typedef struct Event
{
    DataPool dataPool;
    const char* description;
} Event;

template <Event* event, int index>
class EventTransmitter
{
    public:
    EventTransmitter()
    {
        std::cout<<(event+index)->description<<"\n";
    }
};

static Event ev1{ {{'d', 4}, {'a', 1}}, "Description 1"};
static Event ev2{ {{'g', 7}, {'b', 6}}, "Description 2"};

static Event evs[2] {
    { {{'d', 4}, {'a', 1}}, "Description 1"},
    { {{'g', 7}, {'b', 6}}, "Description 2"}
};

int main()
{
    //EventTransmitter<&ev1> e1;
    //EventTransmitter<&ev2> e2;
    
    EventTransmitter<evs, 0> e3;
    EventTransmitter<evs, 1> e4;

    return 0;
}  
docp
2020-10-28