繁体   English   中英

参数名模板的参数化模板c ++ 11

[英]Parametrize template by function name 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); }

我不需要成为功能模板,只需采用某种机制即可实现相同功能。

是的,你可以通过调用者的函数指针作为输入T象下面这样:

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

现场演示

您可以将函数作为参数传递。

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

与传递101010建议的具有模板化参数类型的函数指针相比​​,此方法的优点在于,它可以与函数指针以及函子(实现lambda的任意类型的实例operator()

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

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

或者,按照GuyGreer的建议,将其包装在lambda中。

我个人会使用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)

这是一个有用的宏:

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

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

使用:

static const auto printT = OVERRIDES_OF(print);

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

努力理解这里的原理。 在c ++ 14中,我们有带有自动参数的lambda。 这会解决吗?

#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);
}

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

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));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM