&& 在此代码中的优势是什么?
What is the advantage of && in this code?
在下面的代码中,使用&&
的好处是什么?
代码来自
的答案
从 this 问题中,我得到一个 &&
参数意味着它是一个可以被函数修改的引用。
decay_t
可能会阻止编译器将对变量的引用解释为数组,如 What is std::decay and when it should be used?
std::forward
是here描述的完美转发。为什么我们需要这个转发?
谢谢。
#include <iostream>
#include <type_traits>
#include<utility>
class A;
template <typename T>
struct is_A : std::false_type {};
template <> struct is_A<A> : std::true_type {};
template <typename T>
struct is_int : std::false_type {};
template <> struct is_int<int> : std::true_type {};
template <> struct is_int<long> : std::true_type {};
class A{
public:
int val;
void print(void){
std::cout << val << std::endl;
}
template <typename T1>
std::enable_if_t<is_int<std::decay_t<T1>>::value, void>
operator=(T1 && input){
val = 2*std::forward<T1>(input);
}
template <typename T1>
std::enable_if_t<is_A<std::decay_t<T1>>::value,void>
operator=(T1 && Bb){
val = 5*std::forward<T1>(Bb).val;
}
};
int main(void){
A Aa;
A Bb;
int in_a = 3;
Aa = in_a;
Bb = Aa;
Aa.print(); //This should give 6. (3x2)
Bb.print(); //This should give 30. (6x5)
}
实际上,这是一个(让我说)技巧,因此示例代码可以正常工作。
事实上,标准说:
A user-declared copy assignment operator X::operator= is a non-static non-template member function of class X with exactly one parameter of type X, X&, const X&, volatile X& or const volatileX&.
此外:
If the class definition does not explicitly declare a copy assignment operator, one is declared implicitly.
现在,尝试将一个 const 引用复制赋值给变量,例如:
Bb = static_cast<const A&>(Aa);
结果将不再是预期的结果。
无论如何,只要您只处理非 cv 限定的 lvalue/rvalue 引用,答案中使用的转发引用就可以正常工作,如示例代码所示。
它 拦截 一堆特定的类型并完成它的工作。就这些了。
如@Jarod42 的评论所述:
Note that you still have to write the operator=(const A&)
to handle it as it is special.
确实没那么特别。如果您不定义它,那么您在该代码中就没有合适的复制赋值运算符。
正如评论中所说,定义它
[...] is left as an exercise to the reader. :-)
那么,这样做的好处是什么?
提供最小化工作解决方案的捷径。当然,这不是完整的、可用于生产的代码。
在下面的代码中,使用&&
的好处是什么?
代码来自
从 this 问题中,我得到一个 &&
参数意味着它是一个可以被函数修改的引用。
decay_t
可能会阻止编译器将对变量的引用解释为数组,如 What is std::decay and when it should be used?
std::forward
是here描述的完美转发。为什么我们需要这个转发?
谢谢。
#include <iostream>
#include <type_traits>
#include<utility>
class A;
template <typename T>
struct is_A : std::false_type {};
template <> struct is_A<A> : std::true_type {};
template <typename T>
struct is_int : std::false_type {};
template <> struct is_int<int> : std::true_type {};
template <> struct is_int<long> : std::true_type {};
class A{
public:
int val;
void print(void){
std::cout << val << std::endl;
}
template <typename T1>
std::enable_if_t<is_int<std::decay_t<T1>>::value, void>
operator=(T1 && input){
val = 2*std::forward<T1>(input);
}
template <typename T1>
std::enable_if_t<is_A<std::decay_t<T1>>::value,void>
operator=(T1 && Bb){
val = 5*std::forward<T1>(Bb).val;
}
};
int main(void){
A Aa;
A Bb;
int in_a = 3;
Aa = in_a;
Bb = Aa;
Aa.print(); //This should give 6. (3x2)
Bb.print(); //This should give 30. (6x5)
}
实际上,这是一个(让我说)技巧,因此示例代码可以正常工作。
事实上,标准说:
A user-declared copy assignment operator X::operator= is a non-static non-template member function of class X with exactly one parameter of type X, X&, const X&, volatile X& or const volatileX&.
此外:
If the class definition does not explicitly declare a copy assignment operator, one is declared implicitly.
现在,尝试将一个 const 引用复制赋值给变量,例如:
Bb = static_cast<const A&>(Aa);
结果将不再是预期的结果。
无论如何,只要您只处理非 cv 限定的 lvalue/rvalue 引用,答案中使用的转发引用就可以正常工作,如示例代码所示。
它 拦截 一堆特定的类型并完成它的工作。就这些了。
如@Jarod42 的评论所述:
Note that you still have to write the
operator=(const A&)
to handle it as it is special.
确实没那么特别。如果您不定义它,那么您在该代码中就没有合适的复制赋值运算符。
正如评论中所说,定义它
[...] is left as an exercise to the reader. :-)
那么,这样做的好处是什么?
提供最小化工作解决方案的捷径。当然,这不是完整的、可用于生产的代码。