按函数名称c ++ 11参数化模板

时间:2015-12-14 15:45:03

标签: c++ templates c++11

具有以下功能

void print(int a) { cout << a << endl; }
void print(std::string a) { cout << a << endl; }

您可以执行以下模板

template <class T> void printT(T a) { print(a); }

是否有一些参数化函数名称的机制? 像这样:

template <class T, class F> void anyT(T a) { F(a); }

我不需要成为一个功能模板,只需要一些机制来实现同样的功能。

6 个答案:

答案 0 :(得分:1)

是的,你可以将调用者作为一个函数指针传递,作为输入T,如下所示:

template <class T> void anyT(T a, void(*f)(T)) {
  f(a);
}

Live Demo

答案 1 :(得分:1)

您可以将该功能作为参数传递。

template <class T, class F>
void anyT(T a, F f) {
    f(a);
}

与传递101010提出的模板化参数类型的函数指针相比​​,它的优势在于它适用于函数指针和函子(实现operator()的任何类型的实例,如lambdas。) p>

缺点是在自由模板化参数的上下文中获取重载函数的函数指针会很棘手。您需要使用

void (*f)(int) = print;
anyT(a, f);

或者,将其包装在GuyGreer提出的lambda中。

答案 2 :(得分:1)

我个人会选择101010的解决方案,但您似乎不想将函数指针作为函数参数传递,而只是作为模板参数传递。以下是您可以这样做的方法:

    #include <string>

    template <class T, void(*func)(T)>
    void anyT(T t)
    {
        func(t);
    }

    void print(int i){}
    void print(std::string s){}

    int main()
    {
        anyT<int, print>(1);
        anyT<std::string, print>("hello");
    }

不幸的是,这意味着你必须每次都为函数指定模板参数,这是一个拖累。

我认为更好的解决方案是使用通用模板参数和lambda:

   template <class T, class F>
   void anyT(T t, F f)
   {
       f(t);
   }

   auto printT = [](auto i){print(i);}
   anyT(0, printT);

lambda是必要的,因为直接传递print是不明确的,编译器不会知道你的意思是print(int)还是print(std::string)

答案 3 :(得分:1)

这是一个有用的宏:

#define OVERRIDES_OF(...) [](auto&&...args)->decltype(auto){ return __VA_ARGS__ (decltype(args)(args)...);}

结果是无状态lambda转发到提供的令牌。

使用:

static const auto printT = OVERRIDES_OF(print);

现在printT是一个包装print所有覆盖的对象。

答案 4 :(得分:0)

努力理解这里的理由。在c ++ 14中,我们有lambdas和auto参数。这会解决吗?

#include <iostream>

int main()  {


    int a = 1;
    std::string str = "string";

    auto print = [] (const auto& a) { std::cout << a << std::endl; };

    print(a);
    print(str);
}

答案 5 :(得分:0)

您可以使用函数指针传递函数:

template <class T> void anyT(T a, void(*F)(T)) { F(a); }

但是你不能传递lambda:

auto printStr = [](std::string a) { cout << a << endl; };
anyT(foo, printStr); // This won't compile

另一种方法是使用std::function

template <class T>
void anyT(T a, std::function<void(T)> F) { F(a); }

或通用模板参数:

template <class T, class F>
void anyT(T a, F func) { func(t); }

这有一个缺点,它无法解决重载函数,但您可以使用辅助函数:

template<typename F>
std::function<F> make_function(F *funPtr) {
    return std::function<F>(static_cast<F*>(funPtr));
}

并按照以下方式致电anyT

string foo = "foo";
anyT(foo, make_function<void(std::string)>(&print));