这些超载有必要吗?
我必须编写一个库,其中包含一个采用两个字符串参数的函数:
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
构造函数,只需使用第一个版本。编写此重载只是避免在有人仅传递 const char*
的情况下实例化无用的 std::string
。
但现在我想知道:这种重载真的有必要还是只是过早的优化?
另外,我觉得这在某种程度上不完整:我是否还应该写 void foo(const char* arg1, const std::string& arg2)
和 void foo(const std:: string& arg1, const char* arg2)
重载?如果我有 3 个、4 个或更多 (n
) 个参数怎么办?我应该写 2n 重载吗?
简而言之,您是否遇到过类似的情况?你做了什么选择,为什么?
谢谢。
I have to write a library which contains a function that takes two strings parameters:
void foo(const std::string& arg1, const std::string& arg2);
My library is going to be used by some people that don't like C++ and are only used to const char*
.
To satisfy their likes, I changed the prototype:
void foo(const char* arg1, const char* arg2);
And made my first version a simple inline call:
inline void foo(const std::string& arg1, const std::string& arg2)
{
foo(arg1.c_str(), arg2.c_str());
}
Of course, thanks to the std::string
constructors, it would have worked almost the same way with just the first version. Writing this overload just avoids instanciating useless std::string
in the case someone passes only const char*
.
But now I wonder: is this overload really necessary or is it just premature optimization ?
Also, I'm feeling like this is somehow incomplete: should I write also void foo(const char* arg1, const std::string& arg2)
and void foo(const std::string& arg1, const char* arg2)
overloads ? What if I have 3, 4 or more (n
) parameters ? Should I write 2n overloads ?
In short, have you ever faced a similar situation ? What choices did you made and why ?
Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
在我看来,有两个重载来处理组织内共存的两种不同的编程风格是合理的。
从技术上讲,这不仅仅是一种优化:
const char*
可以是extern "C"
,因此对于来自其他语言的绑定可能有用,或者甚至来自跨越 dll 边界且标准库实现不兼容的其他 C++ 代码。std::string
可能会抛出bad_alloc
,因此如果它不能以其他方式失败,那么const char*
版本会很有用(如果您有C 样式字符串并希望在 nothrot 上下文中使用它。另请注意,原则上
c_str()
可能会抛出bad_alloc
,但我怀疑任何实现实际上都会抛出异常。2n 重载对我来说似乎不值得 - 如果有人混合
string
和char*
那么这不仅仅是编程风格的差异,他们由于某种原因实际上正在使用混合格式。由于他们已经在使用两者,因此他们可以自行转换。这一切都假设该函数足够简单,您很乐意使用 const char* 参数来实现实际工作。如果基于
string
的实现要简单得多(例如,如果需要大量代码才能使其异常安全),那么无论如何,这可能会提高效率,因此不要提供任何重载,让它们的const char*
转换为string
。IMO it's reasonable to have two overloads to handle two different programming styles that co-exist within your organization.
Technically it's not just an optimization:
const char*
can beextern "C"
, so might be useful for bindings from other languages, or even from other C++ code across a dll boundary with incompatible standard library implementation.std::string
can throwbad_alloc
, so if it cannot otherwise fail then theconst char*
version is useful if you have a C-style string and want to use it in a nothrow context.Also beware that in principle
c_str()
can throwbad_alloc
, but I doubt that any implementations actually do.2n overloads doesn't seem worthwhile to me - if someone is mixing
string
andchar*
then it's not just a programming style difference, they're actually using mixed formats for some reason. Since they're using both already, they can convert for themselves.This all assumes that the function is simple enough that you're happy to implement the actual work with
const char*
parameters. If the implementation based onstring
would be significantly simpler (for example if it takes significant code to make it exception-safe otherwise), then that probably wins over efficiency anyway, so don't provide any overloads, let theirconst char*
convert tostring
.只要您想使用 C++(而不是 C),第二个似乎就没有必要了,如果您有这样的情况:
您可以使用
std::string
和的所有组合来调用它>char*
为:As long as you want to work with C++ (and not in C), the second one seems unneccessary, if you've this:
You can call this with all combinations of
std::string
andchar*
as:如果 const char * text 永远不为 null,则可以使用 string,因为它有隐式构造函数,因此 string 类版本就足够了。另一方面:如果 const char * text 可能为 null,则会生成运行时错误。
还有一件事:在 DLL 接口上,STL 并不是一个很好的选择。因此,如果该函数是 DLL 接口的一部分,则可以使用 C 样式字符串。
我可以这样做:
If
const char * text
is never null, you could usestring
, because it has implictit constructor, sostring
class version could be enough. In other hand: ifconst char * text
could be null, it generates runtime error.One more thing: on DLL interface STL is not really good option. So if the function is part of a DLL interface, you may use C style strings.
I may do it in that way:
在这种情况下,您可能只需使用 (const char*,const char*) 并要求每个使用 std::string 的人都使用 c_str()。这样就不会有任何内存分配开销,只有人们必须编写额外的 c_str() 。
In that case, you could probably just have the (const char*,const char*) and ask everyone using std::string to use c_str(). That way there won't be any memory allocation overhead, only the extra c_str() that people will have to code up.
告诉他们要勇敢地学习他们的编译器编译的语言。您采用 std::string,因为这就是 C++ 中的做法,如果他们不喜欢它,那么他们可以获得 C 编译器。
Tell them to man up and learn the language that their compiler compiles. You take
std::string
, because that's how to do it in C++, and if they don't like it, then they can get a C compiler.我认为你目前的做法是正确的。在其中重载
const char*
并提供一个也提供std::string
服务的包装器。如果你的同事要使用 C 风格的字符指针,那么最好这样做(现在的方式)。参见以下案例;
演示。正如您所看到的,字符指针可能并不总是与 std::string 配合良好;那么为什么要冒险呢。即使人们可能不会进行这样的编码;但为了长期可维护性,您仍应避免此类潜在危险。
在函数内部,您始终可以选择使用
const char*
中的std::string
并编写您的算法。I think your present approach is correct. Where you overload for
const char*
and provide a wrapper which also servesstd::string
.If your colleagues are going to use C-style character pointer than it's better to do that way (present way). See following case;
Demo. As you can see that character pointers may not go well always with
std::string
; so why to take chance. Even though people may not do such coding; still you should avoid such potential hazards for long time maintainability.Inside the function you can always choose to have
std::string
fromconst char*
and write your algorithm.