无法从括号括起来的初始化程序列表转换为std元组 [英] Could not convert from brace-enclosed initializer list to std tuple

查看:551
本文介绍了无法从括号括起来的初始化程序列表转换为std元组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为更大项目的一部分,我正在玩 std :: tuple 和模板;请考虑以下代码:

As part of a bigger project, I'm playing with std::tuple and templates; consider the following code:

template <typename ...T> void foo(tuple<T...> t) {}
void bar(tuple<int, char> t) {}
tuple<int, char> quxx() { return {1, 'S'}; }

int main(int argc, char const *argv[])
{
    foo({1, 'S'});           // error
    foo(make_tuple(1, 'S')); // ok
    bar({1, 'S'});           // ok
    quxx();                  // ok
    return 0;
}

根据此答案 C ++ 17支持 copy-list-initialization 中的元组初始化,但是由于我遇到以下错误(GCC 7.2.0),因此这种支持似乎很有限。 :

According to this answer C++17 supports tuple initialization from copy-list-initialization, however it seems such support is limited since I get the following error (GCC 7.2.0):

main.cpp: In function 'int main(int, const char**)':
main.cpp:14:17: error: could not convert '{1, 'S'}' from '<brace-enclosed initializer list>' to 'std::tuple<>'
     foo({1, 'S'}); // error
                 ^

有什么方法可以在此使用大括号括起来的语法吗

Is there any way I can use brace-enclosed syntax in this scenario?

某些上下文:这将在运算符重载中使用,所以我想我绑定到元组并且无法使用

Some Context : this is going to be used in an operator overload so I guess I'm bound to tuples and cannot make use of variadics, any hint is well-accepted.

额外:铛6也抱怨

prog.cc:12:5: error: no matching function for call to 'foo'
    foo({1, 'S'});           // error
    ^~~
prog.cc:6:31: note: candidate function [with T = <>] not viable: cannot convert initializer list argument to 'tuple<>'
template <typename ...T> void foo(tuple<T...> t) {}


推荐答案

{1,'S'} 类似的带括号的初始列表实际上没有类型。在模板推导的情况下,您只能在某些情况下使用它们-针对 initializer_list< T> 推论(其中 T 是函数模板参数)或相应的参数已由其他参数推导的情况。在这种情况下,这两个条件都不成立-因此编译器无法弄清楚 ... T 应该是什么。

A braced-init-list, like {1, 'S'}, does not actually have a type. In the context of template deduction, you can only use them in certain cases - when deducing against initializer_list<T> (where T is a function template parameter) or when the corresponding parameter is already deduced by something else. In this case, neither of those two things is true - so the compiler cannot figure out what ...T is supposed to be.

因此您可以直接提供类型:

So you can provide the types directly:

foo<int, char>({1, 'S'});

或者您可以自己构建元组将其传递给:

Or you can construct the tuple yourself and pass that in:

foo(std::tuple<int, char>(1, 'S')); // most explicit
foo(std::tuple(1, 'S')); // via class template argument deduction






今天, ClassTemplate< Ts ...> 只能从类型为 ClassTemplate< Us ...> 的表达式中推导或从类似内容继承的类型。假设的建议可以扩展为尝试在表达式上执行类模板参数推导,以查看推论是否成功。在这种情况下, {1,'S'} 不是 tuple< Ts ...> ,而是 tuple __var {1,'S'} 确实成功地推导了 tuple< int,char> ,这样就可以了。这样的提议还必须解决诸如...的问题,如果我们要推导 ClassTemplate< T,Ts ...> 或任何较小的变化,那是什么呢?这是类模板自变量推导允许的(但很多人有时表示有兴趣做到这一点)。


Today, ClassTemplate<Ts...> can only be deduced from expressions of type ClassTemplate<Us...> or types that inherit from something like that. A hypothetical proposal could extend that to additionally try to perform class template argument deduction on the expression to see if that deduction succeeds. In this case, {1, 'S'} isn't a tuple<Ts...> but tuple __var{1, 'S'} does successfully deduce tuple<int, char> so that would work. Such a proposal would also have to address issues like... what if we're deducing ClassTemplate<T, Ts...> or any minor variation, which isn't something that class template argument deduction allows (but is something that many people have at times expressed interest in being able to do).

我今天不知道这样的建议。

I'm not aware of such a proposal today.

这篇关于无法从括号括起来的初始化程序列表转换为std元组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆