Zeb*_*ish 4 c++ assignment-operator
template <typename T>
class MyPointer
{public:
template <typename U>
void operator=(MyPointer<U>&& other)
{
}
char* get() const { return pointer; }
private:
char* pointer;
};
int main()
{
struct B {};
struct D : B{};
MyPointer<B> my_pointer_b;
MyPointer<D> my_pointer_d;
my_pointer_b = my_pointer_d;
}
Run Code Online (Sandbox Code Playgroud)
我得到的错误:
二进制“=”:找不到采用“MyPointermain::D”类型的右侧操作数的运算符(或者没有可接受的转换)
编译器为我使用的特定类型实例化赋值运算符,因此即使它删除了默认运算符,实例化的运算符也应该在那里。
也许gcc 的错误有助于进一步阐明这一点:
<source>:24:20: error: cannot bind rvalue reference of type 'MyPointer<main()::D>&&' to lvalue of type 'MyPointer<main()::D>'
24 | my_pointer_b = my_pointer_d;
| ^~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
您的MyPointer<U>&&不是转发参考。它是一个右值引用。
来自cppreference:
转发引用是一种特殊的引用,它保留函数参数的值类别,从而可以通过
std::forward. 转发参考是:
- 函数模板的函数参数声明为对同一函数模板的 cv 非限定类型模板参数的右值引用:
- [... 汽车&& ...]
这是转发参考
template <typename T> void foo(T&&);
Run Code Online (Sandbox Code Playgroud)
这个不是
template <typename T> void bar(X<T>&&);
Run Code Online (Sandbox Code Playgroud)
template <typename U>
void operator=(MyPointer<U>&& other)
Run Code Online (Sandbox Code Playgroud)
在此,MyPointer<U>&&不做转发参考。它是对 some 的右值引用MyPointer<U>,其中U是从参数中推导出来的。
因此,您无法使用左值调用此函数。
如果您想使用转发引用但将其限制为实例MyPointer,那么您可以执行以下操作:
// forward declaration
template <typename T>
class MyPointer;
template <typename T>
struct IsMyPointerInstance : std::false_type {};
template <typename T>
struct IsMyPointerInstance<MyPointer<T>> : std::true_type {};
template <typename T>
concept MyPointerInstance = IsMyPointerInstance<std::remove_cvref_t<T>>::value;
template <typename T>
class MyPointer {
public:
template <typename U> requires MyPointerInstance<U>
void operator=(U&& other) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
(或者如果您不能使用概念,请使用 SFINAE)
| 归档时间: |
|
| 查看次数: |
100 次 |
| 最近记录: |