假设我们有一个类可以写入输出内容
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
请注意,上述解决方案继承了“使用不受约束的转发引用 重载函数”的缺点。这意味着重载集中可行函数的参数类型的所有 ICS 都将被“删除”
关于c++ - 接口(interface)设计: safety of overloaded function taking string and char array,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43819900/