【问题标题】:What interface will copy cstrings, arrays, and other types to instances of the same type?什么接口会将 cstrings、数组和其他类型复制到相同类型的实例中?
【发布时间】:2015-11-19 11:13:13
【问题描述】:

并非一个类型的所有实例都可以复制到具有= 符号的同一类型的另一个实例。

例如, 虽然它可能适用于 ints

int x = 0;
int y = 5;
x = y; //x is now: 5

它不适用于 char 数组

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

char*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 函数将变量复制到另一个实例中会容易得多,而不是解析类型,然后决定如何将适当的副本复制到另一个实例变量中。

【问题讨论】:

  • ....不要?使用std::stringstd::vector 然后你可以做x = y ...
  • 为什么您认为指针分配 (char*) 会不正确?这工作得很好。想要解决什么问题?
  • @Ben 我正在与旧版 C 代码交互。
  • 无需提供新功能,使用std::copy 。 IIRC 你不能在不使用包装类的情况下重载全局赋值运算符。另外,我建议使用 std::array 而不是原始的 c 样式数组。
  • @TrevorHickey 接口,未使用。您可以在需要时使用string.c_str()vector.data() 进行更改。

标签: c++ function overloading copying


【解决方案1】:

这是我对自己问题的尝试:

  #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); 
  }

【讨论】:

  • 我推荐strncpy。您可以使用sizeof(x) 获取其大小,然后将其用作strncpy 中的第三个参数。
  • @Phixle sizeof(x) 将返回指向 char 的指针的大小,而不是数组的长度。在函数声明的参数列表中,char x[]完全等价于char *xx确实是函数体中的指针。
  • @ex-bart 哎呀,对不起。好吧,我的观点是:找到 x 数组的长度并将其用作strncpy() 的第三个参数。它比strcpy 安全得多,几乎一直如此。
【解决方案2】:

这是一个完整的示例,其中添加了couts 以表明选择了正确的重载。

#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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-30
    • 2016-06-22
    • 2015-09-29
    • 2020-11-06
    • 2013-01-15
    • 2019-12-11
    • 2015-05-25
    • 1970-01-01
    相关资源
    最近更新 更多