2016-09-27 3 views
0

Я постоянно сталкиваюсь с ситуацией, когда у меня есть класс, который принимает некоторые параметры шаблона, что я хочу быть общедоступным через CLASS::TYPE. Для этого я всегда делать публичные определений типов, например:Обтекаемый способ создания шаблонных параметров?

template <class Tx> 
Class C 
{ 
public: 
typedef Tx Ty; 

}; 

Это неудобно по 2 причинам:

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

Есть ли лучший способ сделать это?

+1

Это стандартная конвенция в стандартной библиотеке для 'typedef' такого рода как один из небольшого набора имен, например [' element_type'] (http://en.cppreference.com/w/cpp/memory/shared_ptr), ['value_type'] (http://stackoverflow.com/questions/9637094/is-it-a-good-practice-to-always-define-value-type-when-we-define- a-template) или 'type', в зависимости от контекста. Не могу сказать, что я вижу большую часть проблемы с этим. –

+0

@AmiTavory извините, я немного потерял, как это ответ на мой вопрос. Можете ли вы помочь мне немного больше? –

+0

На самом деле это не ответ, просто комментарий. 1. Если вы будете использовать соглашения с библиотекой, параметры шаблона будут UpperCase и будут содержать строчные буквы, поэтому никакого теневого копирования не будет, и, кроме того, было бы относительно легко угадать, что такое имя типа. 2. Поскольку стандартная библиотека делает это, это указывает на то, что нет простой альтернативы. ---- Опять же, я не думаю, что это полноценный ответ, поэтому я написал его как комментарий. –

ответ

1

Вы можете сделать использование decltype синтаксиса, дедукции и тегами диспетчеризации:

template <class Tx> 
struct C { }; 

template <class T> 
struct tag { }; 

template <class T> 
T deduceCTx(tag<C<T>>); 

// now to extract type: 
decltype(deduceCTx(tag<C<int>>{})) a; // a is of type int 

В более общем случае (и при использовании по меньшей мере, C++ 11) вы можете создать функцию выводит, чтобы извлечь какой-либо параметр типа шаблона используя синтаксис шаблона шаблона и VARIADIC шаблонов:

#include <tuple> 

template <class Tx> 
struct C { }; 

template <class T> 
struct tag { }; 

template <size_t N, template <class...> class TT, class... Args> 
typename std::tuple_element<N, std::tuple<Args...>>::type 
    deduceAnyTypeTemplateParameter(tag<TT<Args...>>); 

// now to extract type: 
decltype(deduceAnyTypeTemplateParameter<0>(tag<C<int>>{})) a; // a is of type int 

Если вы используете C++ 14 вы могли бы сделать использование вашей дедукции более удобного путем использования типа псевдонима:

#include <tuple> 

template <class Tx> 
struct C { }; 

template <class T> 
struct tag { }; 

template <size_t N, template <class...> class TT, class... Args> 
typename std::tuple_element<N, std::tuple<Args...>>::type 
    deduceAnyTemplateParameter(tag<TT<Args...>>); 

// now to use passed type: 
decltype(deduceAnyTemplateParameter<0>(tag<C<int>>{})) a; // a is of type int 

template <size_t N, class T> 
using TemplateParameter = decltype(deduceAnyTemplateParameter<N>(tag<T>{})); 

int main() { 
    TemplateParameter<0, C<int>> i; // i of type int 
} 
+1

Аккуратный трюк, но я думаю, что OP искал что-то * менее * неудобно и неуклюже. – molbdnilo

+0

не думаю, что подход не является ни неудобным, ни неуклюжим, но получите свою точку зрения ... –

 Смежные вопросы

  • Нет связанных вопросов^_^