可变参数模板参数 deduction/substitution 失败,元编程

Variadic template argument deduction/substitution failed, metaprogramming

我正在尝试创建递归模板函数,但我一直收到错误消息:

no matching function for call to meuPrint(int&, Separator&, string&)

同时还收到:

candidate: template 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;
}

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

这样的东西是行不通的

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++ 流工具。

在流中使用可变参数要简单得多(您可以忽略格式字符串)