Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
310 views
in Technique[技术] by (71.8m points)

c++ - Initializing from an initializer list, but without {{{{{{{{ ... }}}}}}}}?

I recently stumbles across some problem with initializer lists. Consider a program that stores map-like data

struct MyMapLike {
  MyMapLike(std::map<std::string, int> data)
    :data(std::move(data))
  { }

private:
  std::map<std::string, int> data;
};

That looks straight forward. But when initializing it, it becomes ugly. I want to let it look like

MyMapLike maps = { { "One", 1 }, { "Two", 2 } };

But the compiler doesn't want to accept this, because the above means that it should look for a two-parameter constructor that can accept { "One", 1 } and { "Two", 2 } respectively. I need to add extra braces, to make it look like a single-parameter constructor accepting the { { ... }, { ... } }

MyMapLike maps = { { { "One", 1 }, { "Two", 2 } } };

I would not like to write it like that. Since I have a map-like class, and the initializer has the abstract value of a mapping-list, I would like to use the former version, and be independent of any such implementation details like level of nesting of constructors.

One work around is to declare an initializer-list constructor

struct MyMapLike {
  MyMapLike(std::initializer_list< 
    std::map<std::string, int>::value_type
    > vals)
    :data(vals.begin(), vals.end())
  { }

  MyMapLike(std::map<std::string, int> data)
    :data(std::move(data))
  { }

private:
  std::map<std::string, int> data;
};

Now I can use the former, because when I have an initializer-list constructor, the whole initializer list is treated as one element instead of being splitted into elements. But I think this separate need of the constructor is dead ugly.

I'm looking for guidance:

  • What do you think about the former and latter form of initialization? Does it make sense to be required to have extra braces in this case?
  • Do you consider the requirement for addition of an initializer list constructor in this case bad?

If you agree with me on that the former way of initialization is nicer, what solutions can you think of?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Since I have a map-like class, and the initializer has the abstract value of a mapping-list, I would like to use the former version

And herin lies the problem: it's up to you to supply the constructors that allow your class to be treated like a map. You called your solution a work-around, but there's nothing to work around. :)

But I think this separate need of the constructor is dead ugly.

It is, but unfortunately since it's your class, you have to specify how the initializer lists work.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...