在这个例子中,是否可以允许扣除元组的模板参数类型?
#include<tuple>
#include<string>
template<class T1, class T2>
void fun(std::tuple<T1, T2> t, std::string other){}
int main(){
fun(std::tuple<double, int>(2.,3), std::string("other")); // ok
fun(std::make_tuple(2.,3), std::string("other")); // ok, but trying to avoid `make_tuple`
fun({2.,3},std::string("other")); // desired syntax but
// giving compilation error: candidate template ignored: couldn't infer template argument 'T1' void fun(std::tuple<T1, T2> t)
}
我添加了第二个参数,以避免在函数fun级别涉及可变参数的解决方案.另外,我试图避免使用make_tuple,至少从用户代码(即在main()中).实际上,只要允许“所需语法”并且在某种程度上可以在稍后阶段推导出它的元素类型,它就不需要是所涉及的元组类型.
(另外,虽然类似,但这与initializer_list无关,因为它在大括号中根本不起作用)
它至少在clang 3.2和gcc 4.7.2中失败了.是否有希望它可以与当前或近期标准一起使用? (例如,future(?)initializer_tuple.)
(这对于通过聚合子元素来增加函数调用的表现力非常有用,但可以讨论这个问题)
注意:对于示例代码,似乎std :: forward_as_tuple比std :: make_tuple更合适,因此不必复制参数:http://en.cppreference.com/w/cpp/utility/tuple/forward_as_tuple.仍然没有像异构初始化列表中有内置语言功能那样好.
最佳答案 不,绝对没有办法.如果元素类型不是同一类型,则扣除失败.如果参数不是std :: initializer_list< T>,则根本不进行推论.无论如何(你是对的,initializer_list与你提供的大括号没有任何关系,但这是扣除工作的简单规则).
模板参数值必须由涉及它们的其他函数参数位置推导出,或者必须明确指定.