解压缩模板模板函数的可变参数?

时间:2012-04-25 18:14:07

标签: c++ c++11

// some arbitrary function 
template<typename T>
void log( T&& obj )
{
    std::cout << obj << std::endl;    
}

// arbitrary transformation
template<typename T>
T convert(T&& obj) { 
     return obj; 
}

template<template <typename> typename F, typename... T>
void callOn( F<T> func,  ///  issue: what's the type of func?                 
             T&&... params)
{
    func(std::forward<T>(convert(std::forward<T>(params)))...);
}

int main()
{   
    callOn(log, -1, -2.0);      
     return 0;
}

这有可能吗?

编译器抱怨:没有匹配函数来调用'callOn(,..&gt;)。为什么?

更新:假设日志不是一元函数

template<typename T>
void log(T&& value) { std::cout << value << std::endl; }

template<typename First, typename... Rest>
void log(First&& f, Rest&&... rest)
{
    std::cout << f << ",";
    log(std::forward<Rest>(rest)...);
}

callOn采用与日志类型不匹配的“模板”类型?如何指定func的类型?

2 个答案:

答案 0 :(得分:2)

使用功能对象。这是一个可编辑的例子:

#include <utility>
#include <iostream>

struct Log
{
    template<typename T> void operator()(T&& t) { 
        std::cout << t << std::endl; 
    }

    template<typename T, typename... Rest> void operator()(T&& t, Rest&&... rest)
    {
        std::cout << t << ", ";
        (*this)(std::forward<Rest>(rest)...);
    }
};

template<typename T>
T convert(T&& obj) {
     return obj;
}

template<typename F, typename... T>
void callOn(F funcobj, T&&... params)
{
    funcobj(std::forward<T>(convert(std::forward<T>(params)))...);
}

int main()
{
    callOn(Log(), -1, -2.17, "abc");
    return 0;
}

答案 1 :(得分:1)

我不认为template <typename> typename F的语法是正确的,而且14.3.3 / 1中规定的标准“模板模板参数的模板参数应该是类模板的名称或者别名模板“,而不是功能模板。如果要传递函数模板,可以将参数声明为函数的指针:

template<typename... T>
void callOn( void (*func)(T&&...params),
             T&&... params)
{
    //same as before
}

调用callOn(log, -1, -2.0);时,T的类型不是从log推导出来的,而是从{-1,-2.0}推导为{int,double},然后是{{ 1}}从指向func的指针初始化。