Как объявить шаблонную функцию с необязательным параметром времени компиляции?

Мне нужна функция с этим интерфейсом.

func<type1,compileoption>( Type2 value)
//or
func<type1>( Type2 value)
</type1></type1,compileoption>

Первый параметр времени компиляции - это тип. Это требуется при каждом вызове функции. Второй параметр времени компиляции является необязательным. Он используется для изменения поведения func. Сама функция настраивается на регулярный тип параметра (Type2).

Можно ли создать такой интерфейс?

Если он не может найти способ подобного поведения? например, что-то, что действует как шаблонная функция, которая принимает два параметра времени компиляции, где вторая необязательна?

Наивный подход не работает.

// invalid syntax
template< typename Type1, typename CompileOption = Default, typename Type2>
void func( Type2 t2 );
// Does the wrong thing.
// CompileOption Parameter now change Type2.
template< typename Type1, typename Type2, typename CompileOption = Default>
void func( Type2 t2 );
//This kinda expresses what I'm looking for
template<typename type2="">
template<typename type1,="" typename="" optional="Default">
void func( Type2 t2 );
</typename></typename>
3 ответа

Я подумал о проблеме и смутил всех остальных. Невозможно написать одну функцию, если не используются расширения С++ 0x. Однако довольно просто написать его с двумя перегруженными функциями.

template< typename Type1, typename Option, typename Type2 >
void func( Type2 t2 )
{ /* ... */ }
template< typename Type1, typename Type2 >
void func( Type2 t2 )
{ func<type1,default,type2>(t2); }
func<int,fast_t>(20.f);
func<float>(30); // uses Default as Option
func<float,default>(30); //exact same call as above.
</float,default></float></int,fast_t></type1,default,type2>


Вы имеете в виду что-то вроде этого?

template<typename type1,="" typename="" type2,="" option="">
void foo (Type2 arg)
{
 ... code ...
}
template<typename type1,="" typename="" type2="">
void foo (Type2 arg)
{
 foo<type1, type2,="" defaultoption="">(arg);
}
</type1,></typename></typename>

Изменить: приведенный выше фрагмент работает, но имеет недостаток, который Type2 должен быть явно указан в вызовах.

Я должен признать, что я не могу придумать хорошего полного шаблона для этого; ближайший я мог бы получить, используя пустые аргументы метода:

struct DefaultOption { ... } DEFAULT;
struct OtherOption { ... } OTHER;
template<typename type1,="" typename="" type2,="" option="">
void foo (Type2 arg, Option)
{
 ... code ...
}
template<typename type1,="" typename="" type2="">
void foo (Type2 arg)
{
 foo<type1, type2="">(arg, DEFAULT);
}
</type1,></typename></typename>

Это позволяет звонить в форме

foo<std::string>(1, DEFAULT);
foo<std::string>(1.0, OTHER);
foo<std::string>("Hello");
</std::string></std::string></std::string>

Мне любопытно, каков реальный ответ на эту загадку.


Вы всегда можете попробовать

template<typename type1,="" typename="" optional="Default">
struct A
{
 template<typename type2="">
 void func( Type2 t2 ) {
 // function body
 }
};
</typename></typename>

Возможно, это то, что вам нужно.

licensed under cc by-sa 3.0 with attribution.