可变参数模板参数推导/替换失败,元编程

时间:2017-03-29 18:32:15

标签: c++ c++11 metaprogramming variadic-templates function-templates

我试图创建一个递归模板函数,但是我不断收到错误:

  

没有用于调用meuPrint的匹配函数(int&,Separator&,string&)

同时也接受:

  

候选:   模板字符串meuPrint(U ...,Separator&,string&)。

struct Separator {};    

template<class ...U>
string meuPrint( U ...b , Separator &placeholder , string& text )
{//end
    char buffer[200];
    sprintf( buffer , text.c_str() , b... );
    return buffer;
}
template<class ...T, class ...U>
string meuPrint( U ...b , Separator &placeholder , string& text , string value , T ...a )
{//string
    return meuPrint( b... , to_lower( value ) , placeholder , text , a... );
}

template<class V, class ...T, class ...U>
string meuPrint( U ...b , Separator &placeholder , string& text , V value , T ...a )
{//middle
    return meuPrint( b... , value , placeholder , text , a... );
}

template<class ...T>
string meuPrint( std::string _text , T ...a )
{//start
    Separator placeholder;
    return meuPrint( placeholder , _text , a... );
}

int main( int n , char** args )
{
    string o = meuPrint(  string( "hello %i world" )  ,  8 );
    std::cout << o << std::endl;
    return 0;
}

这里的目标不一定是小写参数,而是测试一个概念。我不明白为什么编译器在后来告诉我一些有效的候选人时仍然无法推断。

1 个答案:

答案 0 :(得分:0)

这样的事情无法发挥作用

template<class V, class ...T, class ...U>
string meuPrint( U ...b , Separator &placeholder , string& text , V value , T ...a )

经验法则:你只能有一包必须在参数列表末尾的参数。

因此,您可以合理地编写(并且编译器可以推断)类似

的内容
template <typename V, typename ... T>
string meuPrint(V value, T ... a)

但以下内容将失败

template <typename V, typename ... T>
string meuPrint(T ... a, V value)

两包参数,如下所示,

template <typename ... U, typename ... T>
string meuPrint(U ... u, T ... t)

无法推断(包u和包t之间的边界在哪里?)。

如果你有两包参数,你必须用std::tuple之类的东西收集它们;

之类的东西
template <typename ... U, typename ... T>
string meuPrint(std::tuple<U ...> u, std::tuple<T ...> t)

但使用可变元组可能有点困难。

关闭主题建议:你正在使用C ++ 11;不是旧的C.扔掉sprintf()并使用C ++流设施。

使用流的变量参数(您可以忽略格式字符串)非常简单