我有一个带有两个类型参数的 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 的模板类。)