Как использовать структуру, объявленную с 'constexpr' в качестве параметра шаблона? - PullRequest
1 голос
/ 24 апреля 2020

Изображение имеет следующую структуру:

typedef struct {
    int a;
    int b[2];
    int c;
} DataParameters;

В конкретной ситуации c вы знаете все эти значения во время компиляции:

constexpr DataParameters p = {
    .a = 5,
    .b = {3, 3},
    .c = 12
};

Затем вы хотите создать шаблонную функцию, которая использует значения a, b, c. Следующий синтаксис действителен, так как структура объявлена ​​как constexpr.

template<int A, int B_0, int B_1, int C>
void doSomething() {
    ...
}

doSomething<p.a, p.b[0], p.b[1], p.c>();

Но давайте представим, что у вас есть структура, которая намного больше, и вам не нужен огромный список параметров шаблона. Есть ли лучший способ сделать это? Я пробовал следующее, но получаю ошибки компилятора:

template<const DataParameters& P>
void doSomething() {
    ...
}

doSomething<p>();

Есть предложения?

1 Ответ

3 голосов
/ 24 апреля 2020

Начиная с C ++ 11 вы можете иметь template <const DataParameters& P> с объектами, которые имеют c длительность хранения и внешнюю или внутреннюю связь.

Начиная с C ++ 17 вы можете иметь template <const DataParameters& P> с объектами которые имеют c срок хранения (ограничение связи было снято)

Начиная с C ++ 20 вы можете иметь template <DataParameters P>. Параметр нетипичного типа может быть (начиная с C ++ 20):

  • литеральный тип класса со следующими свойствами:
    • все базовые классы и не статические c члены данных являются публикуемыми c и неизменяемыми, а
    • типы всех базовых классов и не статичные c членами данных являются структурными типами или (возможно, многомерными) их массивами.

https://en.cppreference.com/w/cpp/language/template_parameters

struct DataParameters // don't use C style typedef
{
    int a;
    int b[2];
    int c;
};

template <const DataParameters& x>
void foo() {}

constexpr DataParameters gp{};

void test_ref_global()
{
    foo<gp>(); // ok since C++11
}

void test_ref_local()
{
    static constexpr DataParameters p{};    
    foo<p>(); // ok since C++17
}

template <DataParameters x> // ok since C++20
void bar() {}

auto test_val()
{
    constexpr DataParameters p{};
    bar<p>(); // ok since C++20
}
...