提问者:小点点

使用具有可变模板参数的类型特征


我试图制作一个类似python print函数的print函数,我在强制变量参数的类型方面遇到了问题,我希望它们被限制为const char*

下面是我到目前为止的代码:

#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;
}

我希望print函数中的可变模板参数仅接受常量字符*


共2个答案

匿名用户

这样做不需要std::tuple,您可以限制函数只使用std::enable_if复制const char*,如下所示

#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;
}

匿名用户

如果您确实想只接受常量字符*,可以使用static_assert这样做(如果您支持C++17):

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