我必须编写一个包含一个带两个字符串参数的函数的库:
void foo(const std::string& arg1, const std::string& arg2);
我的图书馆将被一些不喜欢C ++并且仅用于const char*
的人使用。
为了满足他们的喜好,我改变了原型:
void foo(const char* arg1, const char* arg2);
让我的第一个版本成为一个简单的内联调用:
inline void foo(const std::string& arg1, const std::string& arg2)
{
foo(arg1.c_str(), arg2.c_str());
}
当然,多亏了std::string
构造函数,它与第一个版本的工作方式几乎相同。编写此重载只会避免在有人仅通过std::string
的情况下实现无用的const char*
。
但现在我想知道:这种过载真的有必要还是只是过早优化?
另外,我觉得这在某种程度上是不完整的:我还应该写void foo(const char* arg1, const std::string& arg2)
和void foo(const std::string& arg1, const char* arg2)
重载吗?如果我有3个,4个或更多个(n
)参数怎么办?我应该写2 n 重载吗?
简而言之,您是否遇到过类似情况?你做了什么选择以及为什么?
谢谢。
答案 0 :(得分:4)
IMO合理地有两个重载来处理组织中共存的两种不同的编程风格。
从技术上讲,它不是只是优化:
const char*
可以是extern "C"
,因此可能对其他语言的绑定很有用,甚至可能对来自dll边界的其他C ++代码与不兼容的标准库实现有用。std::string
可以抛出bad_alloc
,所以如果它不能失败,那么如果你有一个C风格的字符串并希望在一个C风格的字符串中使用它,则const char*
版本很有用。 nothrow context。还要注意原则c_str()
可以抛出bad_alloc
,但我怀疑任何实现都会实现。
2 n 重载对我来说似乎不值得 - 如果有人混合string
和char*
那么它不仅仅是编程风格的区别,它们实际上正在使用混合格式由于某种原因。由于他们已经使用了两者,他们可以自己转换。
这一切都假定该功能足够简单,您很乐意使用const char*
参数实现实际工作。如果基于string
的实现会明显更简单(例如,如果它需要大量代码使其异常安全),那么无论如何这可能胜过效率,所以不要提供任何重载,让他们的{ {1}}转换为const char*
。
答案 1 :(得分:2)
只要你想使用C ++(而不是C语言),第二个似乎是不必要的,如果你有这个:
void foo(const std::string& arg1, const std::string& arg2);
您可以将std::string
和char*
的所有组合称为:
char *ca, *cb;
std::string sa, sb;
//...
foo(ca,cb); //char*, char*
foo(sa,cb); //std:string, char*
foo(sa,sb); //std::string, std::string
foo(ca,sb); //char*, std::string
答案 2 :(得分:1)
如果const char * text
永远不为null,则可以使用string
,因为它具有implictit构造函数,因此string
类版本就足够了。另一方面:如果const char * text
可以为null,则会生成运行时错误。
还有一件事:在DLL接口上,STL并不是一个很好的选择。因此,如果函数是DLL接口的一部分,则可以使用C样式字符串。
我可以这样做:
#include <string>
using namespace std;
void foo( const string arg0, const string arg1 )
extern "C" _declspec( dllexport ) void foo( const char * arg0, const char * arg1 )
{
string string_arg0, string_arg1;
if ( arg0 != 0 )
string_arg0 = arg0;
if ( arg1 != 0 )
string_arg1 = arg1;
foo(string_arg0, string_arg1);
}
答案 3 :(得分:0)
我认为你现在的做法是正确的。你为const char*
重载的地方,并提供一个也提供std::string
的包装器。
如果你的同事打算使用C风格的字符指针而不是那样做(现在的方式)。见以下案例;
char *p = 0;
foo(p);
void foo (const string &s)
{ // runtime error
}
Demo。正如您所看到的那样,角色指针可能不会始终与std::string
一致;那么为什么要抓住机会呢。尽管人们可能不会做这样的编码;仍然应该避免这种潜在的危险,以便长期维护。
在函数内部,您始终可以选择std::string
中的const char*
并编写算法。
答案 4 :(得分:0)
在这种情况下,您可能只需要(const char *,const char *)并让每个人使用std :: string来使用c_str()。这样就不会有任何内存分配开销,只有人们必须编写代码的额外c_str()。
答案 5 :(得分:0)
我的图书馆将被一些不喜欢C ++的人使用 仅用于const char *。
告诉他们操作并学习编译器编译的语言。你接受std::string
,因为这是在C ++中如何做到的,如果他们不喜欢它,那么他们可以得到一个C编译器。