【问题标题】:C++ template function aliases as variadic template argumentsC++ 模板函数别名作为可变参数模板参数
【发布时间】:2016-11-18 00:37:54
【问题描述】:

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

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

我做错了什么?

#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("%d\n", *up1);
  printf("%d\n", *up2);
}

【问题讨论】:

  • This 工作,但这真的是你想要的界面吗..?这对我来说就像一个XY problem
  • 我可能会重构以更改界面,但我仍然有兴趣了解潜在问题。为什么在这种情况下可变参数不能与模板别名一起使用?
  • allocator&lt;T&gt; allocator&lt;T, empty-pack&gt; 这是 std::unique_ptr&lt;T&gt;() 然后调整为 std::unique_ptr&lt;T&gt; (*)()
  • 有道理,T.C.是否可以以这样的方式定义模板,以便分配器可以使用可变参数?我不能做 allocator 因为模板参数是在可变参数 Args 参数之前定义的。

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


【解决方案1】:

您可以改为允许并推断可能有状态的函子的类型 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("%d\n", *up0);
  printf("%d\n", *up0b);
  printf("%d\n", *up0c);
  printf("%d\n", *up1);
  printf("%d\n", *up1b);
  printf("%d\n", *up1c);
}

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

Live DEMO here

【讨论】:

  • 我做了,但我的代表(新帐户)少于 15 个,因此不显示。
猜你喜欢
  • 1970-01-01
  • 2011-08-26
  • 1970-01-01
  • 2013-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-01
  • 1970-01-01
相关资源
最近更新 更多