使用{},{}将多个std :: pair传递给可变参数模板构造函数, [英] Passing multiple std::pair to variadic template constructor using { }, { }

查看:120
本文介绍了使用{},{}将多个std :: pair传递给可变参数模板构造函数,的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到一个问题,我真的不知道如何解决。我想在构造函数中使用 {} 大括号,但由于某种原因im gettin compialtion错误传递变量ammount的对。我尽可能地简化了类。

  class MyPairs 
{
public:

MyPairs(std :: pair< char,int>&& pair)
{
pairs [pair.first] = pair.second;
}

template< typename ... Args>
MyPairs(std :: pair< char,int>&& pair,Args& ... args)
{
pairs [pair.first] = pair.second;
MyPairs(std :: forward< Args>(args)...);
}

private:
std :: map< char,int>对;

};

int main()
{
MyPairs p1(// okay,constructor expects pairs
std :: pair< char,int>('a',1 ),
std :: pair< char,int>('b',2)
);

MyPairs p2(//好的,编译器知道它是std :: pair< char,int>在构造函数中
{'c',3}
);

MyPairs p3(//错误,由于某种原因,现在他不知道是std :: pair< char,int>,std :: pair< char,int>
{'d ',6},
{'e',5}
);
}



当然,我可以写 std :: pair< char,int>('a',1),但 p>

为什么编译器在使用 {} 大括号时不知道如何匹配函数?


为什么编译器不知道怎么解决?使用 {} 大括号时匹配函数?


参数分别推导。例如,考虑这:

 模板< typename A,typename B& 
void foo(A a,B b){
}

调用 foo(1,3.14)然后 A 将被推导为 int B 将被推导为 double 。这两个参数完全分开处理。第一个参数 int 不会告诉我们第二个参数。编译器必须独立推导出第二个参数,而不依赖于第一个参数。



同样的逻辑适用于可变参数模板。可变参数模板中的每个参数都单独处理。事实上,你的构造函数的第一个参数是 std :: pair< char,int> 告诉你毕竟,您可以试试这个:

  MyPairs p(
{'d',6},
1,
3.14,
Hello,world!
);

,编译器将调用variadic构造函数并推导出可变参数 int double 和一个字符串。



因此,当您尝试以下操作时:

  MyPairs p(
{'d',6},
{'e',5}
);

编译器必须尝试推导 {'e' 5} 。它应该有什么类型?记住,编译器必须独立于第一个参数推导它的类型。很清楚,我们人类,你希望它 std :: pair ,但有编译器不知道。所以编译器给出一个错误,说它不知道如何处理这些额外的参数。



为了给一个更简单的例子,你的代码大致相当于这样做:

  template< typename A> 
void bar(A a){
}

bar({'d',6});

编译器不清楚您要 A 被推断为 std :: pair 。毕竟,它可能是很多不同的东西。


I encountered a problem which i dont really know how to solve. I want to pass variadic ammount of pairs in constructor, using { } braces, but for some reason im gettin compialtion error. I kept class as simple as possible

class MyPairs
{    
    public:

        MyPairs(std::pair<char, int>&& pair)
        {
            pairs[pair.first] = pair.second;
        }

        template <typename ... Args>
        MyPairs(std::pair<char, int>&& pair, Args&& ... args)
        {
            pairs[pair.first] = pair.second;
            MyPairs(std::forward<Args>(args)...);
        }

    private:
        std::map<char, int> pairs;

};

int main()
{   
    MyPairs p1( // okay, constructor expects pairs
        std::pair<char, int>('a', 1),
        std::pair<char, int>('b', 2)
    );

    MyPairs p2( // okay, compiler knows that it is std::pair<char, int> in constructor
        { 'c',3 }
    );

    MyPairs p3( // error, for some reason now he doesnt know it is std::pair<char, int>, std::pair<char, int>
        { 'd',6 },
        { 'e',5 }
    );
}

Of course i can write std::pair<char, int>('a', 1) for every argument, but {'a', 1} is much more conventient.

Why compiler doesnt know how to match function when using { } braces ?

解决方案

To focus on this question:

Why compiler doesn't know how to match function when using { } braces?

The reason is because each parameter is deduced separately. For example, consider this:

template <typename A, typename B>
void foo(A a, B b) {
}

If I call foo(1, 3.14) then A will be deduced as int and B will be deduced as double. The two parameters are treated totally separately. The fact that the first one is int does not tell us anything about the second parameter. The compiler has to deduce the second parameter all on its own, independent of the first parameter.

This same logic applies to variadic templates. Each parameter in a variadic template is treated individually. The fact that the first parameter to your constructor is a std::pair<char, int> tells you nothing about the later parameters. You could, after all, try this:

MyPairs p(
    { 'd',6 },
    1,
    3.14,
    "Hello, world!"
);

and the compiler would call the variadic constructor and deduce the variadic arguments as int, double, and a string. Each parameter is treated individually.

So when you try the following:

MyPairs p(
    { 'd',6 },
    { 'e',5 }
);

The compiler has to try and deduce the type of { 'e',5 }. And what type should it have? Remember, the compiler has to deduce its type separately from the first parameter. It's clear to us humans that you want it to be std::pair, but there compiler does not know that. So the compiler gives an error saying it doesn't know what to do with those extra parameters.

To give a slightly simpler example, your code is roughly equivalent to doing this:

template <typename A>
void bar(A a) {
}

bar({ 'd', 6 });

It's not clear to the compiler that you want A to be deduced as a std::pair. It could, after all, be a whole lot of different things.

这篇关于使用{},{}将多个std :: pair传递给可变参数模板构造函数,的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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