为什么我的模板不接受初始化列表

发布于 2024-10-13 01:33:08 字数 612 浏览 0 评论 0原文

我创建了一个模板,如下所示,

template<typename T>
void f(T const& t) { }

我希望它可以由容器调用,也可以由初始值设定项列表调用。我认为它会是 initializer_list,调用如下。

f({1, 2, 3});

但 GCC 的行为就好像它不符合标准一样

m.cpp: In function 'int main()':
m.cpp:6:25: warning: deducing 'const T' as 'const std::initializer_list<int>'
m.cpp:4:6: warning:   in call to 'void f(const T&) [with T = std::initializer_list<int>]'
m.cpp:6:25: warning:   (you can disable this with -fno-deduce-init-list)

有人能解释我如何在没有警告的情况下完成这项工作吗?谢谢!

I have created a template as follows

template<typename T>
void f(T const& t) { }

I wanted for this to be callable by containers but also by initializer lists. I thought it would be initializer_list<int>, when called as follows.

f({1, 2, 3});

But GCC behaves as if it's not Standards compliant

m.cpp: In function 'int main()':
m.cpp:6:25: warning: deducing 'const T' as 'const std::initializer_list<int>'
m.cpp:4:6: warning:   in call to 'void f(const T&) [with T = std::initializer_list<int>]'
m.cpp:6:25: warning:   (you can disable this with -fno-deduce-init-list)

Can anyone explain how I can make this work without warnings? Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

动次打次papapa 2024-10-20 01:33:08

像 {1,2,3} 这样的“事物”不符合表达式的条件。它没有类型。因此,不进行类型推导。但 C++0x 对“auto”做出了显式例外,因此

auto x = {1,2,3};

实际上有效,并且 decltype(x) 将是 initializer_list。但这是一个特殊规则,仅适用于汽车。我猜他们想要制作这样的循环

for (int x : {2,3,5,7,11}) {
   ...
}

,因为这种循环利用了特殊规则。

至于解决问题,您可以添加一个 initializer_list 重载作为“包装器”:

template<class T>
inline void outer(initializer_list<T> il) {
   inner(il);
}

我没有对此进行测试,但我目前的理解是它应该可以工作。

A "thing" like {1,2,3} does not qualify as an expression. It has no type. Therefore, no type deduction is done. But C++0x makes an explicit exception for 'auto', so

auto x = {1,2,3};

actually works and decltype(x) will be initializer_list<int>. But this is a special rule that only applies to auto. I guess they wanted to make loops like these

for (int x : {2,3,5,7,11}) {
   ...
}

work since this kind of loop exploits the special rule.

As for solving the problem, you could add an initializer_list<T> overload as a "wrapper":

template<class T>
inline void outer(initializer_list<T> il) {
   inner(il);
}

I didn't test this but my current understanding is that it should work.

遗弃M 2024-10-20 01:33:08

好吧,文档< /a> 说的是

之所以存在此选项,是因为此推导是对 C++0x 工作草案中当前规范的扩展,并且有人担心潜在的重载解析问题。

此信息可能只是过时了(根据来源,最后更新于 2008 年)。据我了解,该扣除已包含在 GCC 中,但预计稍后的标准草案将删除该规则,或至少限制它。

Well, the documentation says that

This option is present because this deduction is an extension to the current specification in the C++0x working draft, and there was some concern about potential overload resolution problems.

This information may simply be outdated (according to the source it was last updated in 2008). As far as I understand this, the deduction was included into GCC but with the expectation that a later draft of the standard would remove the rule, or at least limit it.

我不吻晚风 2024-10-20 01:33:08

谁能解释一下如何在没有警告的情况下完成这项工作?

我不知道 this 是否指的是您引用的确切代码,或者您只是想知道如何使用初始值设定项列表实例化函数模板而不触发警告,但如果是后者并且如果问题仅仅是推导正确的类型,您可以通过调用

f<initializer_list<int>>({1, 2, 3});

It's not beautiful 来避免它,但它可能会避免警告,而无需摆弄编译器命令行参数。

我可能会在附近添加一条注释,解释由于某些 GCC 版本的弱点,您不依赖编译器推导正确的类型。

Can anyone explain how I can make this work without warnings?

I don't know if this refers to the exact code you quoted, or if you just want to know how you can instantiate the function template with an initializer list without triggering warnings, but if it's the latter and if the problem is merely deducing the correct type, you could possibly avoid it by just calling

f<initializer_list<int>>({1, 2, 3});

It's not pretty, but it might avoid the warning without fiddling with the compiler command line arguments.

I'd probably put a comment nearby which explains that you don't rely on the compiler deducing the correct type due to weaknesses in certain GCC versions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文