Как я могу определить тип параметра шаблона в C ++ 11? - PullRequest
3 голосов
/ 13 марта 2020

Я пытаюсь написать функцию, которая заставляет constexpr вычислять через. шаблон. Я написал это, но это работает только для int (будьте осторожны, ошибки с глубиной рекурсии при G CC):

#include <iostream>

template<int val>
constexpr int force_constexpr() { return val; }

constexpr int triangle(int n)
{
    return n ? n + triangle(n - 1) : 0;
}

int main(void)
{
    std::cout << force_constexpr<triangle(0x200)>() << '\n';
}

Обратите внимание, что это только для демонстрационных целей; Я знаю, что номер треугольника можно вычислить с помощью (n+1)*n/2.

Затем я попытался написать обобщенную функцию c, которая, однако, не работает. Это простая ошибка (не удивительно, поскольку она использует T до определения T):

template<T val, typename T = decltype(val)>
constexpr T force_constexpr() { return val; }

как есть (что, очевидно, не будет работать; это вложенный шаблон):

template<typename T>
template<T val>
constexpr T force_constexpr() { return val; }

и для этого требуется тип передаваемого аргумента:

template<typename T, T val>
constexpr T force_constexpr() { return val; }

Как это сделать, не передавая тип в качестве параметра в шаблон? Или, другими словами, как я могу определить тип параметра шаблона?

Я ищу решение C ++ 11, но приветствуются решения для других стандартов.

Ответы [ 2 ]

4 голосов
/ 13 марта 2020

Вы ищете auto параметры шаблона в C ++ 17:

#include <iostream>

template<auto T>
auto *singleton()
{
    static const decltype(T) solo{T};

    return &solo;
}

int main()
{
    const int *p=singleton<42>();

    std::cout << "The meaning of life: " << *p << std::endl;

    return 0;
}

Укажите параметр шаблона как auto и используйте decltype для определения его типа.

Я не верю, что это возможно до C ++ 17, так как это именно тот случай использования, для которого параметры шаблона auto были добавлены в стандарт . Концептуально, до этого не мог этого сделать.

0 голосов
/ 13 марта 2020

C ++ 17 представляет auto в качестве параметра шаблона не тип:

template <auto val>
constexpr auto force_constexpr() { return val; }

Ранее вы действительно блокировали с помощью

template<typename T, T val>
constexpr T force_constexpr() { return val; }

Вы можете ввести MACRO для упрощения использования:

#define AUTO(v) decltype(v), (v)

А потом

std::cout << force_constexpr<AUTO(triangle(0x200))>() << '\n';
...