C++模板函数别名为可变参数模板参数

C++ template function aliases as variadic template arguments

本文关键字:参数 变参 别名 函数 C++      更新时间:2023-10-16

我正在尝试创建一个模板,允许调用方指定自己的格式良好的分配方法,但是我在传递可变参数模板参数时遇到问题。

如果我不传递任何参数,一切都按预期工作;但是,如果我传递一个或多个参数,我会收到编译错误"函数调用的参数太多"。

我做错了什么?

#include <cstdio>
#include <memory>
template <typename T, typename... Args>
using allocator = std::unique_ptr<T>(Args...);
template <typename T, allocator<T> A, typename... Args>
std::unique_ptr<T> get(Args... args) {
  return A(args...);
}
int main() {
  auto up1 = get<int, std::make_unique<int>>();  // Works
  auto up2 = get<int, std::make_unique<int>>(1);  // Too many arguments
                                                  // expected 0, have 1
  printf("%dn", *up1);
  printf("%dn", *up2);
}

您可以改为允许和推断可能的有状态函子 A 的类型。再加几个大括号,但更难弄错:

#include <cstdio>
#include <memory>
template <typename T>
struct allocator{
    template<typename... Args>
    auto operator()(Args&&... args) const { 
        return std::make_unique<T>(std::forward<Args>(args)...);
    }
};
template <typename T, typename A = allocator<T>>
auto get(A a=A{}) {
    return [a](auto... args){ 
        return a(args...); 
    };
};

int main() {
  auto up0 = get<int>()(); 
  auto up1 = get<int>()(1); 
  auto up0b = get<int>(allocator<int>())();
  auto up1b = get<int>(allocator<int>())(1);
  auto up0c = get<int>([](auto ... args){ return std::make_unique<int>(args...); })();
  auto up1c = get<int>([](auto ... args){ return std::make_unique<int>(args...); })(1);
  printf("%dn", *up0);
  printf("%dn", *up0b);
  printf("%dn", *up0c);
  printf("%dn", *up1);
  printf("%dn", *up1b);
  printf("%dn", *up1c);
}

另请注意,我也在allocator中使用make_unique,但您可以制作一个接受指针的版本来构造unique_ptr

现场演示在这里