Вывод типа параметра шаблона c ++

У меня есть такой шаблон в C ++

template<typename T, T* P> struct Ptr {};

так что я могу использовать это как так:

const int i = 0;
Ptr<int, &i> ptr;

или же

Ptr<decltype(i), &i> ptr;

Но я не хочу указывать тип int или личность i дважды, я хочу использовать только

Ptr<&i> ptr;

и пусть компилятор выяснит int введите часть сама.

Как я могу объявить мой шаблон для этого?

Я читал этот вопрос, но в ответе используются макросы, это нехорошо:
шаблон шаблона с ++?

я могу сделать это просто по шаблону без макросов? Я использую Visual C ++ 2013.

10

Решение

ОБНОВИТЬ

представил «P0127R2 Объявление не типовых параметров шаблона с автоmsgstr «, позволяющий объявить нетиповые параметры шаблона с auto в качестве заполнителя для фактического типа:

template <auto P> struct Ptr {};

То есть, P является нетиповым параметром шаблона. Его тип может быть выведен с decltype(P),

auto На шаблон списка параметров распространяются общеизвестные правила вычета и частичного упорядочения. В вашем случае тип может быть ограничен, чтобы принимать только указатели:

template <auto* P> struct Ptr {};

Обратите внимание, что использование синтаксиса auto достаточно даже для более детальной проверки, например:

template <typename F>
struct FunctionBase;

template <typename R, typename... Args>
struct FunctionBase<R(*)(Args...)> {};

template <auto F>
struct Function : FunctionBase<decltype(F)> {};

Также возможно использовать выведенный тип как ограничение для других параметров шаблона:

template <auto I, decltype(I)... Is>
struct List {};

Старый ответ

Поскольку вы спрашиваете о чистом решении на основе шаблонов классов без помощи определений макросов, ответ прост: как сейчас (декабрь 2014 г., ) это невозможно.

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

Ближайший N3601 Неявные параметры шаблона:

Неявные параметры шаблона

Целью этого примера является устранение необходимости в избыточном template<typename T, T t> идиома. Эта идиома широко используется, более 100 тысяч просмотров в Google.

Цель состоит в том, чтобы иметь возможность заменить объявление шаблона как template<typename T, T t> struct C; с другой декларацией, чтобы мы могли создать экземпляр шаблона, как C<&X::f> вместо того, чтобы сказать C<decltype(&X::f), &X::f>,

Основная идея заключается в том, чтобы уметь template<using typename T, T t> struct C {/* ... */}; указать, что T должно быть выведено. Для более подробного описания рассмотрим несколько расширенных примеров шаблонных классов и функций.

[…]

Основная идея заключается в том, что передача типа второго параметра шаблона является избыточной информацией, поскольку ее можно вывести, используя вывод обычного типа из параметра второго типа. Имея это в виду, мы предлагаем, чтобы предварительный поиск параметра шаблона с использованием указывает, что он не должен передаваться явно в качестве аргумента шаблона, а вместо этого будет выводиться из последующих нетипизированных аргументов шаблона. Это сразу позволяет нам улучшить удобство использования describe_field следующее.

template<using typename T, T t> struct describe_field { /* ... */ };
/* ... */
cout << describe_field<&A::f>::name;   // OK. T is void(A::*)(int)
cout << describe_field<&A::g>::arity;  // OK. T is double(A::*)(size_t)

Аналогичное предложение включено в N3405 Шаблонные лакомые кусочки:

Т на двоих

Мотивирующим примером является предполагаемая черта типа отражения, дающая свойства члена класса.

struct A {
void f(int i);
double g(size_t s);
};
/* ... */
cout << describe<&A::f>::name;   // Prints "f"cout << describe<&A::g>::arity;  // prints 1

Вопрос в том «Как должно выглядеть объявление описания?» Так как он принимает не шаблонный параметр типа, нам нужно указать тип параметра, используя знакомый (100 000 просмотров в Google) “template<class T, T t>” идиома

template<typename T, T t> struct describe;
[…]

Наша ключевая идея заключается в том, что передача типа второго параметра шаблона является (почти всегда) избыточной информацией, поскольку ее можно вывести, используя вывод обычного типа из параметра второго типа. Имея это в виду, мы предлагаем разрешить describe быть объявленным следующим образом.

template<typename T t> struct describe;
/* ... */
cout << describe<&A::f>::name;   // OK. T is void(A::*)(int)
cout << describe<&A::g>::arity;  // OK. T is double(A::*)(size_t)

Текущий статус обоих предложений можно отслеживать в разделе РГЭ, выпуск 9.

Есть некоторые другие обсуждение предлагая альтернативный синтаксис с auto:

template <auto T> struct describe;
12

Другие решения


По вопросам рекламы [email protected]