使用自动模板类型推断的函数模板参数的列表初始化



下面是说明这个问题的设置。

template <typename T>
struct opt {
const char* name;
T x;
template <typename X>
opt(const char* name, X&& x)
: name(name), x(std::forward<X>(x)) { }
};
template <typename T>
opt(const char*, T&&) -> opt< some_type_transformation<T> >;
template <typename... T>
void function(opt<T>&&... opts) {
// do something with the passed arguments
}

可以使用下面的语法:

function(opt("a",1),opt("b",2.),opt("c",3u));

但是下面的操作不起作用

function({"a",1},{"b",2.},{"c",3u});

理论上,有足够的信息来确定在第二种情况下该怎么做,因为function只接受opt<T>类型的参数,并且T可以使用定义的推导指南来推导。

可以做些什么来启用第二种更简洁的语法吗?

模板实参推导依赖于使用表达式的类型来匹配模板形参中定义的模式。

Copy-list-initialization(在使用带括号的init-list时,所使用类型的名称不能立即可用的情况下使用list-initialization)是一个过程,在此过程中,将一系列值与指定类型的声明进行匹配,以确定使用哪种初始化形式。也就是说,它涉及某种程度的演绎。

你想要做的是有效地涉及到演绎,因为一个带括号的init-list本身没有一个定义良好的类型。您需要使用模板形参中的模式来匹配一组可能的类型及其构造函数与大括号初始化列表的成员。

在模板实参演绎的某些情况下,这样的事情在理论上是可能的,但是准确地说明这些情况是非常困难的,因为模板实参演绎的工作方式本身就非常复杂。因此,标准采用了一种简单的方法,只是完全禁止它:你不能在模板实参推导中涉及的形参上使用copy-list-initialization,句号。

所以没有更短的形式。你只需要把它拼出来。

最新更新