Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why is there a difference between templated recursive calls and fold expressions with type cast or promotion?

#include <array>
#include <type_traits>
#include <iostream>

template<class... Types>
class Test {
 public:
  Test()
    : format_({
      [&] {
      if constexpr(std::is_same_v<Types, int64_t>) {
        return "%ld ";
      } else if constexpr(std::is_same_v<Types, int32_t>) {
        return "%d ";
      } else if constexpr(std::is_same_v<Types, double>) {
        return "%f ";
      }
      }() ...
    }) {}

  template<typename T, typename ... Args>
  void print_recursive(T && v, Args && ... args) {
    size_t i = sizeof...(Types) - sizeof...(args) - 1;
    printf(format_[i], std::forward<T>(v));
    if constexpr(sizeof...(Args) > 0) {
      print_recursive(std::forward<Args>(args)...);
    } else {
      printf("\n");
    }
  }

  void print_fold(Types && ... args) {
    size_t i = 0;
    ([&]{
      printf(format_[i++], args);
    }(), ...);
    printf("\n");
  }

 private:
  std::array<const char*, sizeof...(Types)> format_;
};

int main() {
  Test<int64_t, int32_t, double> t;
  t.print_recursive(1.0, 2, 3.0);
  t.print_fold(1.0, 2, 3.0);
}

OUTPUT:

0 2 3.000000 
1 2 3.000000 

Built and ran with the following:

g++ test.cpp -o test -std=c++17 && ./test

Compiler Info:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

$ gcc --version
gcc (GCC) 9.2.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

In the above example, the format_ array is defined using fold expressions and used in both print calls. Each print call has the same format specifier for the same index. Each print call has the same args past to it as well. However the output is different for the two. Why is that the case?

>Solution :

You print double as an integer in the recursive call. That’s a UB or some other nonsense.

In the fold version you convert them to the appropriate types first.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading