motam
motam

Reputation: 747

Using forward_as_tuple for sending an initializer list

Suppose the blow code:

#include <map>

using namespace std;

int main(int argc, char *argv[])
{
  map<int, std::array<int, 2>> a;

  a.emplace(piecewise_construct,
            forward_as_tuple(1),
            forward_as_tuple({1, 2}));

  return 0;
}

I want to emplace a std::array using an initializer list. But I got this error:

foo.cc: In function ‘int main(int, char**)’:
foo.cc:13:36: error: too many arguments to function ‘std::tuple<_Elements&& ...> std::forward_as_tuple(_Elements&& ...) [with _Elements = {}]’
             forward_as_tuple({1, 2}));
                                ^
In file included from /usr/include/c++/4.8/bits/stl_map.h:63:0,
                 from /usr/include/c++/4.8/map:61,
                 from foo.cc:3:
/usr/include/c++/4.8/tuple:869:5: note: declared here
     forward_as_tuple(_Elements&&... __args) noexcept
     ^

I know that there are many ways to implement this, but my question is about the wrong behavior of forward_as_tuple why it does not simply send the initializer list to the constructor of std::array?

I use c++11 and g++-4.8.4.

Upvotes: 3

Views: 912

Answers (1)

TartanLlama
TartanLlama

Reputation: 65620

forward_as_tuple({1, 2})

Braced initializers can't be perfect forwarded and deduced as std::initializer_lists like that, you need to explicitly convert them:

forward_as_tuple(std::initializer_list<int>{1,2})

However, although std::array can be initialized with braces due to aggregate initialization, it doesn't have a std::initializer_list constructor. If you really want this kind of initialization, you could use std::vector, but you might be better off just constructing the array and hoping that the compiler optimizes for you.

Upvotes: 5

Related Questions