2

Hello how can make it print it more efficient with large element like 20,000 element ? i took very long to compile , i try to follow this static const array of values in Variadic Template C++

but i can't make it work with fold expression, any ideas how to solve this problem

#include <iostream>


template<typename T = int , typename Comp=std::less<T>>
struct Facility
{
  template<T ... list> 
  struct List
  {
    static void print()
    {
      // store in static array to compile faster
      constexpr static T args[sizeof...(list)] = {list...}; 
      // use for idiom for each except the last, but this time in reserve way
      // assgn char* space to empty char first
      const char* space = "";
      if (sizeof...(list) == 0)
      {
        // simple just call space to cout , if not warning no variable used
        std::cout <<'"' <<"Empty List" <<'"' << space  <<std::endl;
      }
      else if  (std::is_same<T, char>::value)
      {
        std::cout << '"';
       ((std::cout << space << args), ...);// compile error
        // simple just call space to cout , if not warning no variable used
        std::cout << '"' << space<< std::endl;
      }
      else
      {
        std::cout << '"';
        // fold expression bracket,L side will execute first 
        // the first round space is empty and later on become space
        (((std::cout << space << list), space = " "), ...);
        std::cout << '"' << std::endl;
      }    
    }  
  }; 




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...>;

int main()
{
    std::cout << "********Testing Basic List Capabilities*********\n";  
    using List1 = IntList<1,2,3,4>;
    using List2 = IntList<9, 0, -1, -200>;
    using List3 = IntList<LONG20000LIST>;
    List1::print();
    List2::print();
    List3::print();

    using String1 = CharList<'a', 'b', 'c'>;
    using String2 = CharList<' ', 'w', 'o', 'r', 'l', 'd' >;
    using EmptyString = CharList<>;
    String1::print();
    String2::print();
    EmptyString::print();
    std::cout << "************Finished Testing *******************\n\n";
}
  • #define LONG20000LIST 0, 1, 2, 3, 4, 5, 6, 7, 8 ,9, 0, 1, 2, 3, 4, 5, 6, 7, 8 ,9, 0, 8 ,9, 0, 1, 2, 3, 4, 5, 6, 7, 8 ,9, 0, 1, 2, 3, 4, 5, 6, 7, 8 ,9, 0, 1, 2, 3, 4, 5, 6, 7, 8 ,9, 0, 1, 2, 3, 4, 5, 6, 7, 8 ,9, 0, 1, 2, 3, 4, 5, 6, 7, 8 ,9, 0, 1, 2, 3, 4, 5, 6, 7, 8 ,9, 0, 1, 2, 3, 4, 5, 6, 7, 8 ,9, 0, 1, 2, 3, 4, 5, 6, 7, 8 ,9, 0, 1, 2, 3, 4, 5, 6, 7, 8 ,9, 0, 1, 2, 3, 4, 5, 6, 7, 8 ,9, 0, 1, 2, 3, 4, 5, 6, 7, 8 ,9, 0, 1, 2, 3, 4, 5, 6, 7, 8 ,20000 – user3770234 Jul 20 '18 at 08:35
  • I can't add the 20000 list define , it over character limit – user3770234 Jul 20 '18 at 08:36
  • 5
    Why do you need to express this 20000 element list as a compile time constant? Can't you just stuff it in a vector then `copy` it into a `std::experimental::ostream_joiner`? – Caleth Jul 20 '18 at 08:58
  • https://stackoverflow.com/questions/46454659/stdexperimentalostream-joiner-and-stdpair found the solution, you can't use std::experimental::ostream_joiner for this case – user3770234 Jul 20 '18 at 10:14

2 Answers2

0

Here my solution , thank all for helping

static void print()
{
  // store in static array to compile faster
  std::vector<T> args = {list...};
  // use for idiom for each except the last, but this time in reserve way
  // assgn char* space to empty char first
  const char* space = "";
  if (sizeof...(list) == 0)
  {
    // simple just call space to cout , if not warning no variable used
    std::cout <<'"' <<"Empty List" <<'"' << space  <<std::endl;
  }
  else if  (std::is_same<T, char>::value)
  {
    std::cout << '"';
    for (auto const& elem : args)
    {
        std::cout << space << elem; 
    }
    std::cout << '"' << space<< std::endl;
  }
  else
  {
     std::cout << '"';
     for (auto const& elem : args)
     {
        std::cout << space << elem; 
        space = " ";
     }
     std::cout << '"' << std::endl;
  }    
}  
  • I think you could have used `constexpr ifs` here. Also even if you have solved your problem, but didn't answer your title question to use fold expressions. Kinda not sure whenever to downvote or not. – R2RT Jul 20 '18 at 10:34
  • I wonder if replace `std::vector args = {list...};` with `T args[sizeof...(list)] = {list...};`, will it still compile slowly? – sandthorn Jul 20 '18 at 16:45
  • What makes it slow is big constexpr data or big built-in array? – sandthorn Jul 20 '18 at 16:58
  • I not sure about how to make it fast in compile time, I searching online, some say template by default is slow in compile time. let see what metaclass in c++20 do – user3770234 Jul 24 '18 at 16:30
  • @R2RT yes I use it on Microsoft compiler, somehow the g++ will complain if using constexpr – user3770234 Jul 24 '18 at 16:31
-1

This is how you need to declare your array:

constexpr static T args[] = {list...};
bolov
  • 72,283
  • 15
  • 145
  • 224
  • then how I replace in this part else { std::cout << '"'; // fold expression bracket,L side will execute first // the first round space is empty and later on become space (((std::cout << space << list), space = " "), ...); std::cout << '"' << std::endl; } – user3770234 Jul 20 '18 at 08:52
  • @user3770234 make it a `for` – bolov Jul 20 '18 at 10:13