如何处理模板化仿函数的默认值

时间:2011-10-11 12:21:19

标签: c++ templates functor

给定这样的函数:

template<typename functor>
void foo(functor const& f)
{
    if (f)
        f(1, 2);
}

我希望能够指定一个默认值,其中f可以设置为类似NULL的内容。此外,对空函数进行虚假调用也是可能的。有没有什么我可以使用(来自标准或boost - 库)而不是自己创造这样的东西?

7 个答案:

答案 0 :(得分:9)

使用空仿函数并将其用作默认模板参数。你不能使用NULL这样的东西,因为你没有指针:

class X
{
    void operator()(...) {}
};

template <typename functor = X>
void foo(functor const& f = X())
{
    f(...);
}

答案 1 :(得分:3)

要么写一个带有什么也不做的重载,要么将无操作仿函数传递给foo

答案 2 :(得分:2)

最简单的方法是创建一个不带参数的重载:

template<typename functor>
void foo()
{
}

如果默认操作取决于template-parameter,则必须明确提供它,因为编译器无法从中推断出它。如果没有,那么你甚至不需要把它变成模板。

答案 3 :(得分:1)

我不想使用重载函数。它似乎是使用自编的“nop-class”是最好的解决方案。

struct nop
{
    void operator()(...) const volatile {}
};

template<typename functor> 
void foo(functor const& f = functor()) 
{
    f(1, 2);
}

int main()
{
    foo<nop>();
    return 0;
}

答案 4 :(得分:1)

我将此作为一个插入式无操作用于我期望一个没有返回任何值的仿函数的情况。

struct VoidNoOp {
    void operator()() const { }
    template<class A>
    void operator()(A a) const { (void)(a); }
    template<class A, class B>
    void operator()(A a, B b) const { (void)(a); (void)(b); }
    template<class A, class B, class C>
    void operator()(A a, B b, C c) const { (void)(a); (void)(b); (void)(c); }
};

以下是任意数量参数的C ++ 11变体:

struct VoidNoOp {
    void operator()() const { };
    template<typename P1, typename... Params>
    void operator()(P1 p1, Params... parameters) {
        (void)(p1);             // we do this just to remove warnings -- requires the recursion
        operator()(parameters...);
    }
};

答案 5 :(得分:0)

问题是functor是由调用者确定的类型,因此它可能没有默认构造函数,或者您依赖的任何其他功能来构建默认值。

那么,你可以使用重载函数吗?

template<typename functor>
void foo(functor const& f)
{
       f(1, 2);
}

template<typename functor>
void foo()
{
}

答案 6 :(得分:0)

可以在运行时存储NULL的函数包装器std::function (C++11)boost::function

#include <functional>
#include <cstdio>

void foo(std::function<void(int, int)> f)
{
    if (f) {
       f(1, 2);
    }
}

void print(int a, int b) { std::printf("%d %d\n", a, b); }

int main()
{
   foo(0);
   foo(print);
}