今天我发现这段代码并没有像我希望的那样起作用。
根据我对L值的知识,应该调用复制构造函数,而对于R值,它应该选择移动构造函数。否则std::move
的目的是什么,除了强制转换为R值之外什么都不做。我期待return obj
将调用复制构造函数,但它调用move。
我知道这里的副本没用,但这是关于规则的。如果我的复制构造函数有副作用并且这是我的情况怎么办(我知道它不应该,但从技术上讲它可以 - 例如:std :: cout call)。
标准中有什么允许这样的行为吗?另外我怎么强制复制?
#include <iostream>
class X
{
public:
X() = default;
X(const X& r): i(r.i)
{
std::cout << "copy ctor" << std::endl;
}
X(const X&& r): i(r.i)
{
std::cout << "move ctor" << std::endl;
}
int i = 0;
};
X foo()
{
X obj;
obj.i = 10;
return obj;
}
int main()
{
X x = foo();
}
移动ctor
移动ctor
答案 0 :(得分:1)
来自cppreference(强调我的):
如果[返回的表达式]是一个左值表达式并且满足或将满足复制省略的条件,除了[返回的表达式]命名一个函数参数,然后重载决策以选择用于初始化的构造函数返回值的执行两次:首先好像[返回的表达式]是一个右值表达式(因此它可以选择移动构造函数或引用const的复制构造函数),如果没有合适的转换是可用的,第二次执行重载决策,使用lvalue [返回表达式](因此它可以选择引用非const的复制构造函数)。 即使函数返回类型与[返回表达式]的类型不同(复制省略需要相同类型),上述规则也适用
长话短说,class ExpandableListViewAdapterDemo extends BaseExpandableListAdapter{
Context context = null;
private List<String> headersList;//semester's name and year
private HashMap<String, List<String>> tableList;//course names with its grades and gpa
static final String TAG = "**Adapter Demo**";
ExpandableListViewAdapterDemo(Context context, List<String> list,
HashMap<String, List<String>> hashMap){
this.context = context;
headersList = list;
tableList = hashMap;
Log.e(TAG, "hashmap list value = "+hashMap.get("Spring 2016"));
Log.e(TAG, "initial table list value = "+tableList.get("Spring 2016"));
printMap(tableList);
//printAll();
Log.e(TAG, "groupCount = "+getGroupCount());
}
void printAll(){
Log.e(TAG, "headers count = "+headersList.size());
for (int i = 0; i < headersList.size() ; i++) {
Log.e(TAG, "header at i="+i+" ,"+headersList.get(i));
}
printMap(tableList);
}
private static void printMap(HashMap mp) {
Iterator it = mp.entrySet().iterator();
while (it.hasNext()) {
HashMap.Entry pair = (HashMap.Entry)it.next();
Log.e(TAG, "#253 : "+pair.getKey() + " = " + pair.getValue());
it.remove(); // avoids a ConcurrentModificationException
}
}
@Override
public int getGroupCount() {
Log.e(TAG, "#299 : table list value = "+tableList.get("Spring 2016"));
return headersList.size();
}
@Override
public int getChildrenCount(int i) {
//Log.e(TAG, "at i="+i+" "+headersList.get(i));
int returns = 0;
Log.e(TAG, "#307 : table list value = "+tableList.get("Spring 2016"));
if (tableList.get(headersList.get(i)) != null)
returns = tableList.get(headersList.get(i)).size();
else
Log.e(TAG, "tableList is null");
Log.e(TAG, "details size = "+returns);
Log.e(TAG, "group count = "+getGroupCount());
int tosubtract = 2 * getGroupCount();
if (returns>tosubtract)
returns = returns - tosubtract - 2;
Log.e(TAG, "child count returns = "+String.valueOf(returns) );
return i;
}
@Override
public Object getGroup(int i) {
Log.e(TAG, "#323 : table list value = "+tableList.get("Spring 2016"));
return headersList.get(i);
}
@Override
public Object getChild(int i, int i1) {
Log.e(TAG, "#329 : table list value = "+tableList.get("Spring 2016"));
return tableList.get(headersList.get(i)).get(i1);
}
@Override
public long getGroupId(int i) {
Log.e(TAG, "#335 : table list value = "+tableList.get("Spring 2016"));
return i;
}
@Override
public long getChildId(int i, int i1) {
Log.e(TAG, "#340 : table list value = "+tableList.get("Spring 2016"));
return i1;
}
@Override
public boolean hasStableIds() {
Log.e(TAG, "#347 : table list value = "+tableList.get("Spring 2016"));
return false;
}
@Override
public View getGroupView(int i, boolean b, View view, ViewGroup viewGroup) {
Log.e(TAG, "#353 : table list value = "+tableList.get("Spring 2016"));
String semesterTitle = (String) getGroup(i);
if (view == null){
LayoutInflater inf = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inf.inflate(R.layout.previous_semesters_result_list_headers, null);
}
TextView semesterName = (TextView) view.findViewById(R.id.semester_name);
semesterName.setText(semesterTitle);
return view;
}
@Override
public View getChildView(int i, int i1, boolean b, View view, ViewGroup viewGroup) {
Log.e(TAG, "#367 : table list value = "+tableList.get("Spring 2016"));
String courseIdTitle = (String) getChild(i, i1);
String gpa = (String) getChild(i, i1+getChildrenCount(i));//previously i1+4
String grade = (String) getChild(i, i1+getChildrenCount(i)+getChildrenCount(i));
if (view == null){
LayoutInflater inf = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inf.inflate(R.layout.previous_semesters_results_list_child, null);
}
TextView courseIdValue = (TextView) view.findViewById(R.id.course_id_column_value);
courseIdValue.setText(courseIdTitle);
TextView gradeValue = (TextView) view.findViewById(R.id.grade_column_value);
gradeValue.setText(grade);
TextView gpaValue = (TextView) view.findViewById(R.id.gpa_column_value);
gpaValue.setText(gpa);
return view;
}
@Override
public boolean isChildSelectable(int i, int i1) {
Log.e(TAG, "#386 : table list value = "+tableList.get("Spring 2016"));
return true;
}
}
隐含地试图在有意义的时候移动你返回的东西。它只会作为最后的手段复制(例如,没有移动构造函数)。