Search code examples
c++c++17fold-expression

c++17 fold expression syntatx


I have problem of make code working of fold expression in line 18 and line 23

I want make it such as have this result

"1 2 3 4"
"9 0 -1 -200"
"abc"
" world"
"Empty List"

As if the list is empty you will print "Empty List", if not, if the type is char it won't print space and if the type is not char, it will print space in between.

I tried using ((std::cout<<" " << list), ...); but it will print extra space which I don't want so I store in a temp string and later erase it.

Anyone can help?

#include <iostream>
#include <string>
template<int ... intlist>
using IntList = typename Facility<int>::List<intlist...>;

template<char ... charlist>
using CharList = typename Facility<char>::List<charlist...>;

template<short ... shortlist>
using ShortList = typename Facility<short>::List<shortlist...>;

template<unsigned short ... shortlist>
using UnsignedShortList = typename Facility<unsigned short>::List<shortlist...>;

template<long ... list>
using LongList = typename Facility<long>::List<list...>;

template<typename T , typename Comp=std::less<T>>
struct Facility
{
  template<T ... list> 
  struct List
  {
    static void print()
    {
      std::string str; 
      str ="\"";
      if(sizeof...(list)== 0)
      {
         str+="Empty List";
      }
      else if (std::is_same<T, char>::value)
      {
        str+=(... + list);
         //((std::cout<< list), ...);
      }
      else
      {
        str+=((" " + list), ...);
        //((std::cout<<" " << list), ...);
        str.erase(0,1);
      }
      str+="\"";
      std::cout << str << std::endl;
    }  
  }; 
};

int main()
{
    using List1 = IntList<1,2,3,4>;
    using List2 = IntList<9, 0, -1, -200>;
    List1::print();
    List2::print();

    using String1 = CharList<'a', 'b', 'c'>;
    using String2 = CharList<' ', 'w', 'o', 'r', 'l', 'd' >;
    using EmptyString = CharList<>;
    String1::print();
    String2::print();
    EmptyString::print();

  }

Solution

  • As I understand you might use:

    template<typename T>
    struct Facility
    {
        template <T ... list>
        struct List
        {
            static void print()
            {
                std::cout << '"';
                if constexpr (sizeof...(list) == 0)
                {
                     std::cout << "Empty List";
                }
                else if constexpr (std::is_same<T, char>::value)
                {
                    ((std::cout << list), ...);
                }
                else
                {
                    [[maybe_unused]]  const char* sep = "";
                    (((std::cout << sep << list), sep = " "), ...);
                }
                std::cout << '"' << std::endl;
            }  
        }; 
    };
    

    With usage:

    int main() {
        Facility<int>::List<>::print();
        Facility<int>::List<42, 42>::print();
        Facility<char>::List<'h', 'e', 'l', 'l', 'o'>::print();
    }
    

    Demo