如何使用可选的编译时参数声明模板化函数?

时间:2010-12-04 00:04:57

标签: c++ templates template-meta-programming

我想要一个具有此界面的功能。

func<Type1,CompileOption>( Type2 value)
//or
func<Type1>( Type2 value)

第一个编译时参数是一个类型。每个函数调用都需要它 第二个编译时参数是可选的。它用于修改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 );

3 个答案:

答案 0 :(得分:1)

你的意思是这样吗?

template<typename Type1, typename Type2, typename Option>
void foo (Type2 arg)
{
    ... code ...
}

template<typename Type1, typename Type2>
void foo (Type2 arg)
{
    foo<Type1, Type2, DefaultOption>(arg);
}

编辑:上面的代码段有效,但缺点是需要在调用中明确指定Type2。

我必须承认,我不能想到一个好的全模板解决方案;我能得到的最接近的是使用空方法参数:

struct DefaultOption { ... } DEFAULT;
struct OtherOption { ... } OTHER;

template<typename Type1, typename Type2, typename Option>
void foo (Type2 arg, Option)
{
    ... code ...
}

template<typename Type1, typename Type2>
void foo (Type2 arg)
{
    foo<Type1, Type2>(arg, DEFAULT);
}

这允许以

形式进行调用
foo<std::string>(1, DEFAULT);
foo<std::string>(1.0, OTHER);
foo<std::string>("Hello");

我很好奇这个难题的真正答案是什么。

答案 1 :(得分:1)

你总是可以尝试

template<typename Type1, typename Optional = Default >
struct A
{
    template<typename Type2>
    void func( Type2 t2 ) {
        // function body
    }
};

也许这就是你需要的。

答案 2 :(得分:0)

我过度思考问题,并且也困惑了其他所有人。除非使用C ++ 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.