Search code examples
c++templatesc++17variadic-templatesvariadic

Using type traits with variadic template arguments


I am attempting to make a print function that functions like a python print function, and I am having issues with enforcing what type the variadic arguments can be, I would like them to be restricted to const char*.

Here is my code so far:

#include <tuple>
#include <iostream>
#include <utility>
#include <type_traits>


template<
  std::size_t I=0,
  typename... Args,
  typename FUNCTION
  >
constexpr void for_each(const std::tuple<Args...>& t, FUNCTION &&func)
{
  if constexpr(I < sizeof...(Args))
  {
    func(std::get<I>(t));
    for_each<I + 1>(t, std::forward<FUNCTION>(func));
  }
}

template<
  typename... Args
  >
constexpr void print(Args... args)
{
  std::tuple t(std::forward<Args>(args)...);
  for_each(t, [=](const char* str)
  {
    std::cout << str << " ";
  });
  std::cout << '\n';
}

int main(void)
{
  print("this", "is", "a", "thing");
  print("this", "is", "not", "a", "thing");
  return 0;
}

I would like the variadic template argument in the print function to only accept const char*


Solution

  • You don't need std::tuple to do that and you can restrict your function to copy const char* only using std::enable_if, as follows

    #include <iostream>
    #include <type_traits>
    
    
    template<typename ... Args>
    constexpr std::enable_if_t<std::is_same_v<std::common_type_t<Args...>,const char*>, void>
    print(Args&&... args)
    {
        ((std::cout << args << " "),...);
        std::cout << '\n';
    }
    int main( )
    {
        print("this", "is", "a", "thing");
        print("this", "is", "not", "a", "thing");
        print(5, "is", "not", "a", "thing");//compile error
        return 0;
    }