2015-08-05 1 views
1

Когда я сталкиваюсь с шаблоном с несколькими аргументами по умолчанию, например.C++ Templates: переопределить некоторые, но не все аргументы по умолчанию?

template<typename ID = int, typename PAYLOAD = std::string> 
class Foo{}; 

Есть ли способ обойти только несколько аргументов по умолчанию, а не все из них?

I.e. вместо того, чтобы писать следующее, чтобы создать класс, который использует целое вместо std::string для параметра PAYLOAD,

typedef Foo<int,int> Bar; 

Могу ли я написать что-то подобное:

typedef Foo<PAYLOAD=int> Bar; 

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

Рассматривая документацию и другие вопросы по StackOverflow, это не представляется возможным, но мне было интересно, может ли кто-нибудь объяснить, почему это не функция?

+0

Afaik это возможно только в Python (возможно, также на других языках скриптов). В C++ нет способа сделать это, о чем я бы знал. – Chris

+0

Обходные способы, например. [увеличение.параметр] (http://www.boost.org/doc/libs/1_58_0/libs/parameter/doc/html/index.html#class-template-parameter-support), см. также http://stackoverflow.com/ q/4209326/ – dyp

+0

Вы также можете использовать некоторый шаблон построителя для достижения синтаксиса, близкого к: 'Foo_builder :: Payload :: type', или указав оба аргумента' Foo_builder :: ID :: Полезная нагрузка :: Тип' (в Любой заказ). – dyp

ответ

2

В дизайне и эволюции C++ Бьярне Страуструп отметил, что существуют предложения по ключевым словам; однако, они были отклонены, так как

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

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

+1

Я знаю, что это мнение комитета, а не обязательно ваше, но думаете ли вы, что можете уточнить, почему это будет считаться «стилем программирования, который не следует поощрять»? –

+0

Конечно. В python нередко можно увидеть функции с 10 или более параметрами, большинство из которых имеют значения по умолчанию, которые были использованы для использования аргументов ключевого слова. Наличие так много входов - плохой запах кода, потому что такие функции трудно поддерживать и менее согласованы. Предложенный рефактор для таких функций состоит в том, чтобы извлекать связанные аргументы в отдельные структуры, которые предоставляют простые способы их создания. –

+0

Важно стараться оставаться на высоком уровне абстракции. 'bool f (double, double, double, double, double, double, double)' ничего не говорит вам, 'bool f (Point &, Point &, double)' начинает предлагать, что происходит :) –

0

Номер

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

0

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

Создайте шаблон с первыми n связанными аргументами. Затем извлеките аргументы и замените нужные.

Для этого необходимо, чтобы первые n аргументов были действительны без позиционных.

Эскиз:

template<class...>struct types{using type=types;}; 
template<class types, class T, size_t index> 
struct replace{ 
    using type=/*types with index replaced with `T`*/; 
}; 
template<template<class...>class Z,class types> 
struct apply;// applies content of types to Z 
template<size_t n, class T>struct rep{}; 
template<class Z, class...reps> 
struct replacing; 
template<template<class...>class Z, class...Ts,class...reps> 
struct replacing<Z<Ts...>,reps...>: 
    apply<Z,replacing_t<types<Ts...>,reps...>> 
{}; 
template<class...Ts,class T0,class n,class...reps> 
struct replacing<types<Ts...>,rep<n,T0>,reps...>: 
    replacing<replace_t<types<Ts...>,T0,n>,reps...> 
{}; 
template<class...Ts> 
struct replacing<types<Ts...>>: 
    types<Ts...> 
{}; 

с _t использования псевдонимов и ряд ОПС остаются пустыми.

Тогда вы можете:

replacing_t<some_template<>,rep<1,int>> 

, который использует аргументы по умолчанию some_template, но заменяет arg1 с int.

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