【问题标题】:c++ parameter pack specification in constructor rather than template构造函数中的c ++参数包规范而不是模板
【发布时间】:2015-07-19 07:06:43
【问题描述】:

与带有参数包的函数声明不同,我发现类需要尖括号中每个参数的类型...

Component<IntegerPair, int, int> temp(40, 5);

...这似乎是多余的。这是我定义Component的方式:

template<typename T, class... T_Args>
class Component
{
public:
  Component(T_Args... args)
    : m_data(args...)
  {}

  T m_data;
};
  1. 有没有办法从上述语句中删除int, int
  2. 如果是,是否可以将其删除?
  3. 另外,我的实例化方式m_data 安全吗?使用时 std::forward&lt;T_Args&gt;(args)...我的编译器告诉我我没有 可以转换所有参数类型的构造函数。

【问题讨论】:

  • 你基本上是在问是否可以从构造函数调用中推断出类模板参数——asnwer 是 no。您需要的是一个“制造商”功能 - 例如 std::make_pair 或构造函数模板。
  • 3:你需要接受一个通用引用T_Args&amp;&amp;才能使用完美转发

标签: c++ templates parameter-passing class-template


【解决方案1】:

一种方法是让构造函数成为模板:

#include <utility>

struct IntegerPair {
    IntegerPair(int, int) {}
};

template<typename T>
class Component
{
public:
  template<typename... T_Args>
  Component(T_Args&&... args)
    : m_data(std::forward<T_Args>(args)...)
  {}

  T m_data;
};

int main()
{
    Component<IntegerPair> c {1,2};
}

这在功能上等同于std::vector 及其成员函数emplace_back。没关系,IMO。错误消息非常神秘,就像在这样的模板结构中通常一样,但是可以通过适当的static_assert 来缓解这种情况。

【讨论】:

  • 这正是我想要的,而且您还修复了转发。为什么要为参数使用花括号?
  • @user3097902 没有特别的原因,它是较新的语法:) 在这种情况下,括号是等效的。
【解决方案2】:

模板参数推导仅适用于函数调用,因此实现您想要的基本模式如下所示:

template<typename T, class... T_Args>
Component<T, T_Args...> makeComponent(T_Args&&... args) {
   return Component<T, T_Args...>(std::forward<T_Args>(args)...);
}

用法:

auto c = makeComponent<IntegerPair>(1, 1)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-10
    • 2016-03-01
    • 1970-01-01
    • 2016-01-02
    • 1970-01-01
    • 1970-01-01
    • 2021-09-19
    • 2013-03-25
    相关资源
    最近更新 更多