https://github.com/MIN-JU-CHO/CppStudy/blob/main/13_2_Move.cpp
// 이동 생성자
MyString(MyString&& ref) noexcept
{
id = ++cnt;
cout << id << " 이동 생성\\n";
size = ref.size;
length = ref.length;
if (size < length)
{
size = length;
}
data = ref.data;
ref.data = nullptr;
}
// 이동 대입 연산자
MyString& operator=(MyString&& str) noexcept
{
cout << "이동\\n";
delete[] data;
size = str.size;
length = str.length;
if (size < length)
{
size = length;
}
data = str.data;
str.data = nullptr;
return (*this);
}

추측 이유:
size = str.size;
length = str.length;
해당 객체가 더 이상 유효한 데이터를 가리키지 않도록 하는 역할?
참고했던 링크
https://ansohxxn.github.io/cpp/chapter15-3/
// 이동 생성자
MyString(MyString&& ref) noexcept
{
id = ++cnt;
cout << id << " 이동 생성\\n";
size = ref.size;
length = ref.length;
if (size < length)
{
size = length;
}
data = ref.data;
ref.length = 0;
ref.size = 0;
ref.data = nullptr;
}
// 이동 대입 연산자
MyString& operator=(MyString&& str) noexcept
{
cout << "이동\\n";
delete[] data;
size = str.size;
length = str.length;
if (size < length)
{
size = length;
}
data = str.data;
str.length = 0;
str.size = 0;
str.data = nullptr;
return (*this);
}

드디어 원인 찾음

따라서 ref.length와 ref.size를 0으로 만들어줌으로써 복사(operator=(const&)) 시에 반드시 new 로 동적할당 해주게끔 (사이즈가 항상 작아서, if문 안으로 들어가게끔) 유도하게 하면 오류가 생기지 않는다.
#include <string>
#include <iostream>
#include <stdlib.h>
using namespace std;
size_t GetLen( string str)
{
return str.size();
}
size_t GetLen(const char* str)
{
return strlen(str);
}
template<typename String, typename... Strings>
size_t GetLen( String str, Strings... strs)
{
return GetLen(str) + GetLen(strs...);
}
void Append(string* str)
{
return;
}
template<typename String, typename... Strings>
void Append(string* origin, String str, Strings... strs)
{
origin->append(str);
Append(origin, strs...);
}
template<typename String, typename... Strings>
string StrConcat( String str, Strings... strs)
{
size_t length = GetLen(str, strs...);
cout << "Length: " << length << "\\n";
string result;
result.resize(length);
result = str;
Append(&result, strs...);
return result;
}
int main(void)
{
string word = "this";
cout << StrConcat(word, " ", "is", " ", "a", " ", "sentence", "\\n");
}
#include <string>
#include <iostream>
#include <stdlib.h>
using namespace std;
size_t GetLen(const string& str)
{
return str.size();
}
size_t GetLen(const char* str)
{
return strlen(str);
}
template<typename String, typename... Strings>
size_t GetLen(const String& str, Strings... strs)
{
return GetLen(str) + GetLen(strs...);
}
void Append(string* str)
{
return;
}
template<typename String, typename... Strings>
void Append(string* origin, const String& str, Strings... strs)
{
origin->append(str);
Append(origin, strs...);
}
template<typename String, typename... Strings>
string StrConcat(const String& str, Strings... strs)
{
size_t length = GetLen(str, strs...);
cout << "Length: " << length << "\\n";
string result;
result.resize(length);
result = str;
Append(&result, strs...);
return result;
}
int main(void)
{
string word = "this";
cout << StrConcat(word, " ", "is", " ", "a", " ", "sentence", "\\n");
}
첫번째 인자를 const String &로 해도 되고, String으로 해도 되는, 둘 다 정상적(좌측값, 우측값)으로 실행되는 이유가 뭘까?
const string &와 const char * 두 타입을 모두 아우를 수 있기 때문이라고 생각했는데,, 더 구체적이고도 논리적인 이유가 필요하다.