【问题标题】:Using type traits with variadic template arguments使用带有可变模板参数的类型特征
【发布时间】:2020-10-27 17:07:59
【问题描述】:

我正在尝试创建一个功能类似于 python 打印函数的打印函数,但我在强制可变参数可以是什么类型时遇到问题,我希望将它们限制为 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 函数中的可变参数模板参数只接受const char*

【问题讨论】:

  • 你为什么要这样限制自己?如果您将 [=](const char* str) 更改为 [=](const auto&amp; elem ) 您的 lambda 可以使用任何已定义 operator &lt;&lt; 的类型。
  • 仅供参考:fmt.

标签: c++ templates c++17 variadic-templates variadic


【解决方案1】:

如果你真的只想接受const char*,你可以这样做,使用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';
}

【讨论】:

  • 感谢您的快速回答,我会尝试实现这一点。
  • for_each 过载是什么?它看起来邪恶而美好。我在寻找时找到了this implementation
  • @TedLyngmo 其 OP 的 for_each
  • @bartop Facepalm... 我需要更仔细地阅读 :-) 所以,你也得到了投票。
【解决方案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;
}

【讨论】:

  • 感谢您的快速回答,这会导致替换失败还是编译失败?
  • @finlaymorrison print(5, "is", "not", "a", "thing"); 会阻止你的编译器编译整个程序
猜你喜欢
  • 2011-09-08
  • 2012-04-23
  • 2014-10-05
  • 1970-01-01
  • 2015-03-30
  • 2020-04-29
  • 2012-11-18
  • 2011-08-29
  • 1970-01-01
相关资源
最近更新 更多