Advertisement Jump to content
tanzanite7

C++ Initializer list woes

Recommended Posts

Given:

template<typename T> struct Thing {
  Thing(std::initializer_list<T> arr) {...}
};

template<typename T> struct Arbiter {
  template<typename ...Args> Arbiter(type stuff, Args ...args) : subject(args...) {...}
  T subject;
};

typedef Arbiter<Thing<int32u>> Arbiter32u;

Arbiter32u test1(stuff, {1U,2U,3U}); // error C2661 : no overloaded function takes 2 arguments
auto wtf = {1U,2U,3U};
Arbiter32u test2(stuff, wtf); // this is fine

Why does 'test1' fail where 'test2' is fine? Presumably the constructor used is removed by SFINAE - but why? SFINAE unfortunately masks out whatever goes wrong leaving me just puzzled :/.

edit:

Found something relevant to the 'auto' special rule: https://stackoverflow.com/questions/26330499/why-is-there-a-special-type-deduction-rule-for-auto-and-braced-initializers-in-c?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa

... still not sure i get it.

Edited by tanzanite7

Share this post


Link to post
Share on other sites
Advertisement
Arbiter32u test1(stuff, {1U,2U,3U});

What is {1U,2U,3U}? Is that just an array of unsigned ints, a std::initializer_list, or? The compiler most likely doesn't know you are wanting to pass a std::initializer_list since your passing it to args. When you use auto the compiler is able to deduce it to a std::initializer_list before passing it to the args.

This would work fine since you are actually passing the list to the args, which represents one object/arg:

Arbiter32u test1(0, std::initializer_list<int32u>({ 1U,2U,3U }));

As a matter of fact, you should be able to do this as well since you are allowing multiple args to be passed:

Arbiter32u test1(0, std::initializer_list<int32u>({ 1U,2U,3U }), 0, 1, 2, 3.0, 4);
  
//OR
  
Arbiter32u test1(0, std::initializer_list<unsigned int>({ 1U,2U,3U }), 0, std::initializer_list<unsigned int>({ 1U,2U,3U }), 2, 3.0, 4);

 

If you add this, just as an example. then it would work fine for just your std::initializer_list so you can use Arbiter32u test1(stuff, {1U,2U,3U}):

template<typename ...Args> Arbiter(int stuff, std::initializer_list<int32u> args) : subject(args) { }

 

Perhaps someone with more knowledge on this would have better information for you.

Edited by AtomicWinter

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!