Constructor for nested initializer lists

为君一笑 提交于 2019-12-03 16:42:46
Johannes Schaub - litb

I believe what you really want to do is to automatically build the right type

template<int S, typename E>
class make_list_type {
public:
  typedef std::initializer_list<
    typename make_list_type<S-1, E>::type
  > type;
};

template<typename E>
class make_list_type<0, E> {
public:
  typedef E type;
};

template<int S>
class ClassA {
  typedef typename make_list_type<S, double>::type initializer_type;

public:
  ClassA(initializer_type l) 
};

As for why your try did not work, see Templates don't always guess initializer list types

In general, the answer is (AFAIK): No. But for your specific case, you might use the knowledge that it all ends with double as the leafs:

class arg_type
{
private:
    bool is_value;
    double d;
    std::vector<arg_type> subs;
public:
    arg_type(double v) : is_value(true), d(v) {}
    arg_type(std::initializer_list<arg_type> l) : is_value(false), subs(l) {}
};

and change your ctor to:

typedef std::initializer_list<arg_type> initializer_type;

ClassA(initializer_type l) {
  // ...
}

Hope it helps...


Update: As pointed out by Mankarse (thanks!), the above has undefined behaviour. Here's a version that should fix it without using Boost:

#include <vector>
#include <memory>
#include <iostream>
#include <initializer_list>

class arg_type
{
private:
    std::shared_ptr<void> subs; // empty => d is valid
    double d;

public:
    arg_type(double v) : d(v) {}
    arg_type(std::initializer_list<arg_type> l);

    void print() const;
};

arg_type::arg_type(std::initializer_list<arg_type> l)
  : subs(std::make_shared<std::vector<arg_type>>(l))
{}

void arg_type::print() const
{
   if( subs ) {
     std::cout << "( ";
     for( const auto& e : *std::static_pointer_cast<std::vector<arg_type>>(subs) ) {
       e.print();
     }
     std::cout << ") ";
   }
   else {
      std::cout << d << " ";
   }
}

struct MyClass
{
   MyClass( std::initializer_list<arg_type> l) {
      for( const auto& e : l ){
         e.print();
      }
   }
};

int main()
{
   MyClass m { 1, 2, { 3, 4, { 6, 7, { 8 }}}, 5 };
}

If you want to play with it, here's the live example.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!