作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个带有两个类型参数的 C++ 模板类 MyClass:
template <typename D, typename S>
struct MyClass {
private:
D d_;
S s_;
};
我想添加一个以 D 和 S 引用作为参数的构造函数,这样它就可以推断出 D 和 S:
template <typename D, typename S>
struct MyClass {
// can bind to lvalues
constexpr MyClass(const D &d, const S &s): d_(d), s_(s) {}
// can bind to rvalues
constexpr MyClass(D &&d, S &&s): d_(std::move(d)), s_(std::move(s)) {}
private:
D d_;
S s_;
};
效果很好。我可以从左值或右值创建对象:
auto c1 = MyClass(1, std::string("Hello")); // rvalues
auto idx = 2;
auto msg = std::string("World");
auto c2 = MyClass(idx, msg); // lvalues
但我只想要一个使用通用引用的构造函数而不是两个每个处理左值和右值。大概是这样的:
template <typename D, typename S>
struct MyClass {
constexpr MyClass(D &&d, S &&s): d_(std::forward<D>(d)), s_(std::forward<S>(s)) {}
private:
D d_;
S s_;
};
它不适用于语句“auto w2 = MyClass(i, j);”。编译器提示
error: no viable constructor or deduction guide for deduction of template arguments of 'MyClass'
auto c2 = MyClass(idx, msg); // lvalues
^
note: candidate function [with D = int, S = std::__1::basic_string<char>] not viable: no known conversion from 'int' to 'int &&' for
1st argument
constexpr MyClass(D &&d, S &&s): d_(std::forward<D>(d)), s_(std::forward<S>(s)) {}
命令行:c++ -std=c++17 test.cpp
,使用Apple clang version 12.0.0 (clang-1200.0.32.6)编译
构造函数似乎只能接受右值。这不是通用引用。所以我的问题是我能否实现通用引用 样式的构造函数? (我还想将 MyClass 保留为具有两个类型参数 D 和 S 的模板类。)
最佳答案
在此代码段中,d 和 s 是不是 通用引用 - 它们是右值引用(因为 D和 S 在类中已通过类实例化已知(推断)。
template <typename D, typename S>
struct MyClass {
constexpr MyClass(D &&d, S &&s): d_(std::forward<D>(d)), s_(std::forward<S>(s)) {}
private:
D d_;
S s_;
};
根据 Scott Meyers: 类型推导需要涉及D&& 和 S&&
类型的变量(并且仅以这种形式!)对于那些要成为通用引用的变量,所以你需要额外的模板参数(所以类型是由类方法(在这种情况下=ctor)实例化推导的):
template <typename D, typename S>
struct MyClass {
template <typename DD, typename SS>
constexpr MyClass(DD &&d, SS &&s): d_(std::forward<DD>(d)), s_(std::forward<SS>(s)) {}
private:
D d_;
S s_;
};
通过构造函数调用启用类模板类型推导可以通过类模板推导指南完成,例如:
template <typename DD, typename SS> MyClass(DD &&d, SS &&s) -> MyClass<DD, SS>
关于c++ - 如何在 C++ 中使用通用引用参数为模板类编写构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64262171/
我是一名优秀的程序员,十分优秀!