gpt4 book ai didi

c++ - 接口(interface)设计: safety of overloaded function taking string and char array

转载 作者:可可西里 更新时间:2023-11-01 18:36:40 26 4
gpt4 key购买 nike

假设我们有一个类可以写入输出内容

class Writer
{
public:
int write(const std::string& str);
int write(const char* str, int len);
//...
};

我对这个、它的灵 active 以及所有这些都很好,直到我意识到

char* buf = new char[n]; //not terminated with '\0'
//load up buf
Writer w;
w.write(buf); //compiles!

那是一个真的讨厌的错误。

我们可以通过一些模板进行一些修改

class WriterV2
{
public:
int write(const std::string& str);
int write(const char* str, int len);
template<typename... Args>
int write(const char*, Args...)
{ static_assert(sizeof...(Args) < 0, "Incorrect arguments"); }
//...
};

但是这个方法有它的问题

WriterV2 w;
w.write("The templating genius!"); //compile error

我该怎么办?什么是更好的设计?

在任何人询问之前,重载 const char (&)[N] does not work .创建一个包装器来执行此操作可能是可行的,但这似乎...有点矫枉过正?

编辑 添加一个方法 write(char*) 并在那里发出错误并不理想。当通过函数传递 buf 时,它可能会变成 const char*

最佳答案

ICS (Implicit Conversion Sequences)正如您所注意到的,在 C++ 中的重载解析过程中会产生令人惊讶的结果,而且也很烦人..

您可以提供所需的必要接口(interface),然后通过利用 partial ordering 谨慎地使用模板来处理 string literal vs const char* 惨败删除不需要的重载。

代码:

#include <iostream>
#include <string>
#include <type_traits>

class Writer
{
public:
int write(std::string&&) { std::cout << "int write(std::string)\n"; return 0; }
int write(const std::string&) { std::cout << "int write(const std::string& str)\n"; return 0; }
int write(const char*, int){ std::cout << "int write(const char* str, int len)\n"; return 0; }

template<std::size_t N = 0, typename = std::enable_if_t<(N > 0)> >
int write(const char (&)[N]) { std::cout << "int write(string-literal) " << N << " \n"; return 0; }


template<typename T>
int write(T&&) = delete;

};

int main(){
char* buf = new char[30];
const char* cbuf = buf;
Writer w;

//w.write(buf); //Fails!
//w.write(cbuf); //Fails!
w.write(buf, 30); //Ok! int write(const char*, int);
w.write(std::string("Haha")); //Ok! int write(std::string&&);
w.write("This is cool"); //Ok! int write(const char (&)[13]);
}

打印:

int write(const char* str, int len)
int write(std::string)
int write(string-literal) 13

Demo


请注意,上述解决方案继承了“使用不受约束的转发引用 重载函数”的缺点。这意味着重载集中可行函数的参数类型的所有 ICS 都将被“删除”

关于c++ - 接口(interface)设计: safety of overloaded function taking string and char array,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43819900/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com