在此示例中,是否可以允许扣除tuple
的模板参数类型?
#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)
}
我添加了第二个参数other
,以避免在函数fun
级别涉及可变参数的解决方案。此外,我试图避免使用make_tuple
,至少从用户代码(即在main()
中)。事实上,只要允许“所需语法”,它就不需要是tuple
类型,并且可以在某个时候推导出它的元素类型。
(另外,虽然类似,但这与initializer_list
无关,因为它在大括号中根本不起作用)
至少在clang 3.2
和gcc 4.7.2
失败。是否有希望它可以与当前或近期标准一起使用? (例如未来(?)initializer_tuple
。)
(这对于通过聚合子元素来增加函数调用的表现力非常有用,但可以讨论这个问题)
注意:对于示例代码,似乎std::forward_as_tuple
比std::make_tuple
更合适,因此不必复制参数:http://en.cppreference.com/w/cpp/utility/tuple/forward_as_tuple。仍然没有像异构初始化列表中有内置语言功能一样好。
答案 0 :(得分:2)
不,绝对没有办法。如果元素类型不是同一类型,则扣除失败。如果参数不是std::initializer_list<T>
,那么根本不进行任何推论(initializer_list
与你给的大括号没有关系是对的,但这是扣除的简单规则上班)。
模板参数值必须由涉及它们的其他函数参数位置推导出,或者必须明确指定。