【问题标题】:Passing initializer as argument将初始化程序作为参数传递
【发布时间】:2014-05-24 20:08:48
【问题描述】:

初始化器有类型吗?如果有,是什么?在这种情况下,我怎样才能使下面的代码工作?

template <typename T>
int f(T a)
{
    return 0;
}

int main()
{
    f({1,2});
}

它给出以下错误:

c.cpp:32:2: 错误:没有匹配的函数调用“f” f({1,2}); ^ c.cpp:18:5: 注意:候选模板被忽略:无法推断模板参数'T' int f(T a) ^ 产生 1 个错误。

【问题讨论】:

  • {1,2} 甚至不是一个表达式。除了std::initializer_list&lt;pattern&gt; 形式的参数模式(其中pattern 类似于T const&amp;)之外,它无法推断。
  • [temp.deduct.call]/1 " 如果从P 中删除引用和cv-qualifiers 为某些P' 提供std::initializer_list&lt;P'&gt; 并且参数是初始化列表,则执行推导相反,对于初始化列表的每个元素,将 P' 作为函数模板参数类型,并将初始化元素作为其参数。否则,初始化列表参数会导致参数被视为非推导上下文。"

标签: c++ c++11 initializer


【解决方案1】:

在编写f({1,2}) 时,您使用的是list initialization

如果您想将 initializer list {1,2} 原样传递给函数,您可以这样做:

#include <initializer_list>
#include <iostream>

template <typename T>
int f(std::initializer_list<T> a) {
    for(const T& x : a) {
        std::cout << x << ", " << std::endl; // do something with the element
    }
    return 0;
}

int main() {
    f({1,2});
}

【讨论】:

  • 您可能是指循环内的语句使用x,而不是a
  • @aschepler:谢谢!修好了。
【解决方案2】:

如果你想为列表中的每个值执行你的函数,你可以这样做:

#include <iostream>

template <typename T>
int f(T a)
{
    return 0;
}

int main()
{
    for (int a : {1,2})
        std::cout << f(a) << std::endl;
}

注意这需要兼容 c++11 的编译器

如果你想将列表传递给你的函数,那么像这样:

#include <iostream>
#include <initializer_list>

template <typename T>
int f(T a)
{
    return 0;
}

int main()
{
    std::cout << f(std::initializer_list<int>{1, 2}) << std::endl;
}

【讨论】:

  • 你也可以利用auto+uniform init的misdesign特性:auto il{1,2}; f(il);
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-25
  • 1970-01-01
  • 1970-01-01
  • 2020-11-09
  • 1970-01-01
  • 2014-01-21
  • 1970-01-01
相关资源
最近更新 更多