Не все экземпляры типа могут быть скопированы в другой экземпляр того же типа с =
знак.
Например,
хотя это может работать на Интс:
int x = 0;
int y = 5;
x = y; //x is now: 5
Это не будет работать на массивы символов:
char x[32]="data to overwrite";
char y[32]="new data";
x = y; //incorrect
или же другие массивы:
int x[5] = {1,2,3,4,5};
int y[5] = {6,7,8,9,10};
x = y; //incorrect
или же символ * s:
char* x="data to overwrite";
char* y="new data";
x = y; //incorrect
Как я могу написать перегруженную функцию, которая позволит мне делать следующее?
int x = 0;
int y = 5;
Copy(x,y); //x is now: 5
char x[32]="data to overwrite";
char y[32]="new data";
Copy(x,y); //x is now: "new data"
int x[5] = {1,2,3,4,5};
int y[5] = {6,7,8,9,10};
Copy(x,y); //x is now: {6,7,8,9,10}
char* x="data to overwrite";
char* y="new data";
Copy(x,y); //x is now: "new data"
* Я предполагаю, что любые абстрактные типы данных выполняют необходимую работу в своем перегруженном операторе присваивания (или из мелкой копии, предоставленной компилятором)
Зачем тебе это нужно?
Чтобы упростить тестирование частей унаследованной базы кода C, я хотел бы сгенерировать несколько оболочек C ++ вокруг нескольких компонентов. Из-за странного дизайна кода на C есть много косвенных моментов, от которых я хотел бы избавиться. Таким образом, было бы намного проще скопировать переменные в другой экземпляр с помощью простого Copy
вместо анализа типов и принятия решения о том, как сделать соответствующую копию в другой переменной экземпляра.
Вот полный пример, с cout
s показывает, что выбраны правильные перегрузки.
#include <algorithm>
#include <cstddef>
#include <iostream>
#include <ostream>
// default
template<class T>
void Assign(T& dst, const T& src)
{
dst = src;
std::cout << "assign (default)" << std::endl;
}
// arrays
template<class T1, std::size_t n>
void Assign(T1 (&dst)[n], const T1 (&src)[n])
{
std::copy(src, src+n, dst);
std::cout << "assign (array)" << std::endl;
}
// pointers
template<class T1>
void Assign(T1 *&dst, T1 *src)
{
// DANGER: memory leaks/double frees
// not exactly sure what is supposed to happen here
// same as default for now...
// ok as long as only string constants are passed around
// (as is the case in the example)
dst = src;
std::cout << "assign (pointer)" << std::endl;
}
int main() {
{
int x = 0;
int y = 5;
Assign(x,y); //x is now: 5
}
{
char x[32]="data to overwrite";
char y[32]="new data";
Assign(x,y); //x is now: "new data"}
{
int x[5] = {1,2,3,4,5};
int y[5] = {6,7,8,9,10};
Assign(x,y); //x is now: {6,7,8,9,10}
}
{
const char* x="data to overwrite";
const char* y="new data";
Assign(x,y); //x is now: "new data"}
}
Выход:
g++ -std=c++11 -g -Wall -O3 check.cc -o check && ./check
assign (default)
assign (array)
assign (array)
assign (pointer)
Вот моя попытка ответить на мой собственный вопрос:
#include <algorithm>
#include <cstring>
//catch all
template <typename T>
void Copy(T &x, T y)
{
x = y;
}
//overload on static array copying
//(T[N] = T[N])
template <typename T, size_t N>
void Copy(T(&x)[N], T(&y)[N])
{
std::copy(std::begin(y), std::end(y), std::begin(x));
}
//overload on copying of null terminated data
//(char array = cstring)
void Copy(char x[], const char y[])
{
//assumes x is >= to y
//not sure if I can use strncpy somewhow
strcpy(x, y);
}