从初始值设定项列表中提取模板类型

Extract template type from initializer list

本文关键字:提取 类型 列表      更新时间:2023-10-16

我对C++11模板化代码有问题。我有一个模板功能

    template <typename T> 
    f(const std::vector<T>& v)
    {
      /* do something here*/
    };

当我调用f(v)时,其中v被声明为std::vector<some_type> v;,程序编译得很好。然而,如果我将初始值设定项列表传递给f,比如f({a,b,c}),其中abc都是相同的类型,比如说some_type,我会得到一个编译错误:couldn't infer template argument 'T',所以我必须在调用f时手动指定类型。也就是说,例如,当abc都是ints时,f<int>({a,b,c});编译得很好。如果函数被定义为取std::vector<T>的参数,有没有办法从标准初始化器列表中推断模板类型T?基本上,我只想在调用f时能够调用f({initializer_list});,而无需在尖括号中指定initializer_list的元素类型。

您可以定义

template<typename T>
void f(const std::initializer_list<T>& v) {
  f(std::vector<T>(v));
}

为了实现这一点,initializer_list必须具有某种明确的类型,因此f({0, 1.41421, 2.71828, 3.14159 })不起作用,但f({0.0, 1.41421, 2.71828, 3.14159})会起作用。

日本政府在回答另一篇SO帖子时表示,

大括号init list{…}是C++11的新的统一初始化语法,如果变量的类型已知,它可以用于初始化任何自动、静态或成员变量

由于当您调用时,传递的参数类型是已知的:

f<int>({a,b,c});

它是有效的。

使用时:

f({a,b,c});

必须推导出类型。因此,它不起作用。

如果你想利用a类型,你可以使用:

f<decltype(a)>({a,b,c});

这应该行得通。