c++ - 调用作为参数接收的可变参数模板的可变参数模板

标签 c++

我有一个可变参数模板函数,我想用它有条件地向另一个可变参数模板函数添加参数。这是一个最小的示例,但我无法编译它:

// Copyright 2019 Google LLC.
// SPDX-License-Identifier: Apache-2.0

#include <utility>

template<typename... Args>
void f(Args&&... args) {
  // does something with args
}

template<typename T, typename... Args>
void g(T&& t, int i, Args&&... args) {
  if (i != 0) t(i, std::forward<Args>(args)...);
  else t(std::forward<Args>(args)...);
}

int main() {
  g(f, 0, 0);
  return 0;
}

上述代码的 clang 输出是:

main.cpp:15:7: error: no matching function for call
      to 'g'
      g(f, 0, 0);
      ^
main.cpp:9:10: note: candidate template ignored:
      couldn't infer template argument 'T'
    void g(T&& t, int i, Args&&... args) {
         ^
1 error generated.

使用宏,它会像这样工作(如果我用这个宏替换上面的 g 函数编译):

// Copyright 2019 Google LLC.
// SPDX-License-Identifier: Apache-2.0

#define g(t, i, args...) \
  if((i) != 0) (t)((i), args); \
  else (t)(args);

有没有办法不用宏就可以完成这项工作?

最佳答案

直接传递 f 是行不通的,因为函数指针必须指向特定的函数模板实例,该实例必须在 g 调用点实例化。使用模板模板模板参数可以创建可以作为参数传递而无需事先实例化的函数签名构建器:

#include <utility>

template<typename... Args>
void f(Args... args) {
  // does something with args
}

template<typename... Args> struct
get_f
{
    static constexpr auto & get() { return f<Args...>; }
};

template<template<typename...> typename T, typename... Args>
void g(int i, Args&&... args) {
  if (i != 0) T<int, Args...>::get()(i, std::forward<Args>(args)...);
  else T<Args...>::get()(std::forward<Args>(args)...);
}

int main() {
  g<get_f>(0, 0);
  return 0;
}

关于c++ - 调用作为参数接收的可变参数模板的可变参数模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57946779/

相关文章:

c++ - getnameinfo() - 反向 DNS 查找(IP 地址到主机名)C/C++

c++ - c++什么时候需要用#include

c++ - 使用 C 或 C++ 从控制台获取原始输入

python - 将 c++ vector 传递给 python 并返回

c++ - 检测窗口何时停止移动?

c++ - 类包装设计问题

c++ - C++ 中的对象实例化是否存在显着的固有成本?

C++ 变量总是以零出现

c++ - enable_if 和 is_move_constructible 允许不可移动类型,但 require 不允许

c++ - 将类模板作为函数参数传递