Why does an argument type of std::set accept {} as argumet but boost::container::flat_set does not?

68 Views Asked by At

I converted some methods from argument type const std::set<>& to const boost::container::flat_set<>& with the same template types being passed. Now I have to change every occurrence of calls to these methods where the argument was {} and have to replace them with typename().

Why is this, and is there some easier way?

boost_1_60_0 being used -- don't blame me!

To compile:

g++ -std=c++11 test_set.cpp -D__FLAT__

or

g++ -std=c++11 test_set.cpp

The error message is clear -- and I couldn't read the original.

I guess the {} can only be interpreted as an argument list, as the type is unknown.

#include <set>
#include <map>
#include <boost/container/flat_set.hpp>
#include <boost/container/flat_map.hpp>

#ifndef __FLAT__
typedef std::map<int, int> MAP;
typedef std::set<MAP> SET;
#else
typedef boost::container::flat_map<int, int> MAP;
typedef boost::container::flat_set<MAP> SET;
#endif

static void show(const SET&)
{
}

int main(int, char**)
{   
    //SET s({});
    show({});
}
1

There are 1 best solutions below

0
cbuchart On

As mentioned in a comment, constructors for std::set are non-explicit while boost::container::flat_set are explicit.

Explicit constructors require you to explicitly indicate the type, and when you do {} you are not.

Also, in the commented line you are first constructing the object and then calling the copy constructor of SET. As the Boost's container has an explicit constructor, compiler is not able to deduce the type you need there so it cannot deduce that the {} was for creating a SET.

You can fix it in several ways:

SET s{};
SET s{SET{}}; // ridiculous usage, just to illustrate the problem
show(SET{});