2015-09-08 3 views
3

В C++ существует 2 типа шаблонов (насколько мне известно): классы шаблонов и функции шаблона. Почему шаблон шаблона невозможен? (будь то класс, функция или другой шаблон). Было ли это когда-либо рассмотрено в стандартах? Разрывает ли он синтаксис/дух Си ++? Я знаю, это может показаться сумасшедшим, и легко обойти.Почему вы не можете создать шаблон шаблона?

Что можно с C++:

template<bool b> 
class TemplateDependingOnBool 
{ 
public: 
    template<typename T> 
    class TheTemplateWeWant{}; 
} 

Что было бы здорово:

template<bool b> 
template<typename T> 
class TheTemplateWeWant{}; 

и назвать его в стиле на основе политик (что, где это действительно интересно):

template<typename T, template<typename> class ThePolicy = TheTemplateWeWant<true> > 
class Foo {}; 

Способ, который теперь можно использовать, - использовать:

template<typename T, 
    template<typename> class ThePolicy = TemplateDependingOnBool<true>::TheTemplateWeWant > 
class Foo{}; 

который не очень элегантный.

EDIT:
Я знаю, что могу шаблон на 2 параметров. Цель состоит в том, чтобы использовать базовый шаблонный шаблон (шаблонный шаблон) как нечто само собой, будь то в шаблоне или в шаблоне (как показано в моем примере). Основанный на политике дизайн является ссылкой на Modern C++ Design Andrei Alexandrescu, что является основной причиной, почему функция, которую я прошу, может быть полезна (поскольку шаблоны используются в качестве параметров шаблона).

+6

Вы должны написать 'шаблон класса TheTemplateWeWant {};' – nwp

+2

При упоминании «на основе политик в стиле» это заставляет меня думать о [понятий предложение] (https://isocpp.org/blog/2013/02/concepts-lite-constraining-templates-with-predicates-andrew-sutton-bjarne-s). –

+1

Я не понимаю, что вы здесь спрашиваете. – Barry

ответ

6

С C++ 11 вы ошибаетесь, предполагая только два типа шаблонов. Есть также type aliases которые позволяют

template <bool b, typename T> 
class TheTemplateWeWant { ... }; 

template<typename T> 
using ThePolicy = TheTemplateWeWant<true, T> 
+0

Спасибо, вероятно, самый близкий ответ на то, что я ищу. Он по-прежнему требует другого объявления (мой вопрос касался языка и о IF, а если не ПОЧЕМУ, можно представить и реализовать несколько уровней глубины шаблонов). – maxbc

+0

@maxbc: Раймонд Чен сказал о функциях Windows (но то же самое относится к функциям C++): «Все предложения начинаются с -100, должна быть хорошая причина, чтобы что-то добавить». Это отвечает на ваш вопрос «почему бы и нет?». : потому что язык уже достаточно сложный, как есть. Обратите внимание, что C++ получил этот третий тип шаблона, потому что это довольно простой механизм, который устарел из множества сложных конструкций (см. мой другой ответ на C++ 98, boost.MPL). – MSalters

+0

Это, вероятно, большая часть ответа, который я искал. Мои причины, конечно, не забивают +100, чтобы представить что-то настолько сложное на языке. – maxbc

0

Насколько я знаю, вы просто знаете, что это так, и оно работает так, как вы хотите - класс с шаблонами с двумя параметрами.

template<bool b, typename T> 
class TheTemplateWeWant{}; //valid in C++ 
+1

OP вероятно мечтает о curryfication на шаблонах, или частичная оценка. Он должен изучить Common Lisp (чьи способности метапрограммирования намного лучше, чем в C++ 11) –

+5

Даже если это заканчивается вопросительным знаком, это, вероятно, не вопрос OP. Это скорее ответ, сформулированный как риторический вопрос. –

+3

Совместный вопрос может быть хорошим ответом. – user2079303

4

Если я понять, что вы спрашиваете, правильно (и я не совсем ясно, на ваш вопрос), то вы можете написать шаблон с двумя параметрами:

template <bool b, typename T> 
class TheTemplateWeWant { ... }; 

добавить metafunction частично применять bool:

template <bool b> 
struct PartiallyWant { 
    template <typename T> 
    using type = TheTemplateWeWant<b, T>; 
}; 

, а затем передать его в качестве политики:

template<typename T, 
     template<typename> class ThePolicy = PartiallyWant<true>::type > 
class Foo { ... }; 

Foo<char, PartiallyWant<false>::type> foo; 

Так почему бы не просто наложить шаблоны, как вы предлагаете? Простой ответ: нет причин. Если TheTemplateWeWant имеет два параметра шаблона (bool b и typename T, независимо от того, является ли это «внутренним» классом или нет), тогда мы должны выразить это как таковое. И если мы хотим применять только один тип или другой, это то, что имеет меньше случаев использования, чем общий шаблон, а также разрешимо всего несколькими строками шаблона. Кроме того, что, если бы у нас была такая функция, и теперь я хочу частично применить T вместо b? С несколькими строками шаблона я могу снова выполнить одно и то же, но с расслоением это было бы невозможно.

+0

Я не думаю, что вы должны его обернуть, вы можете просто использовать шаблон. – Melkon

+0

@Melkon Как вы бы использовали шаблон? Он принимает два параметра шаблона, и нам нужно передать его тому, что принимает один параметр шаблона. – Barry

+0

Хм, ты прав, эта абстракция, вероятно, необходима. :( – Melkon

0

То, что вы описываете, является частичной привязкой параметров , так же как std::bind может превратить двоичную функцию в унарную функцию.

Для метапрограммирующего безумия есть Boost.MPL. У них есть шаблон boost::mpl::bind.

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