【发布时间】:2012-04-05 02:56:31
【问题描述】:
希望读到这里的人都知道默认参数:
void setCase (string &str, int form = UPPERCASE)
{
for (char &c : str)
c = (form == UPPERCASE ? c & ~0x20 : c | 0x20); //this bit differentiates english uppercase and lowercase letters
}
int main()
{
string s1 = "HeLlO", s2 = s1, s3 = s1;
setCase (s1, UPPERCASE); //now "HELLO"
setCase (s2, LOWERCASE); //now "hello"
setCase (s3); //now "HELLO" due to default argument
}
使用默认参数的一个缺点是您必须在列表末尾开始使用默认参数。有时这涉及将参数重新排列成一个看起来很愚蠢的顺序。为了解决这个问题,必须进行单独的重载。
让我以一个 Window API 函数 FindWindow 为例,它通过类名、标题或两者来查找窗口:
HWND WINAPI FindWindow( //returns handle to window
__in_opt LPCTSTR lpClassName, //param equivalent to const TCHAR *, classes are like templates for windows
__in_opt LPCTSTR lpWindowName //the text that appears on the title bar (for normal windows, for things like buttons, it's what text is on the button)
);
为了总结这一点,人们可能希望默认搜索选项是标题。有三种理想的实现方式(假设使用了其他包装技术)。完美的解决方案很可能如下:
Window FindWindow (LPCTSTR className = 0, LPCTSTR windowName){...}
第二种解决方案是重载该函数的一个版本以仅接受标题,而另一个版本则接受两者。第三种是切换参数的顺序。
第二个问题的主要问题是,对于更长的列表,随着列表的增长,重载的空间量可能会变得非常大。第三个问题的主要问题是,任何事先使用过这个函数的人都会习惯于首先指定类名。这也适用于常规 C++ 函数。参数往往具有自然顺序。
当然,第一个解决方案的主要问题是它不受 C++ 语言的支持。我的问题是:
将来是否有可能提供此功能?
例如,编译器能否在需要时自动生成适当的重载?
【问题讨论】:
-
不喜欢?使用不同的语言,例如 Python,它使用 keyword arguments。
subprocess.Popen就是一个很好的例子。 -
我可以忍受。我只是想知道(可能还有许多其他人也是如此)这是否会随着新的 C++ 添加进入该语言而改变。我确实记得另一种语言(可能是 Python)很适合参数传递,因为它能够判断参数是默认的还是用户只是传递了默认值。
-
仍然可以计算出哪些列表是明确的,对于
(int a = 0, int b = 1)之类的情况,请坚持当前的从右到左的约定。像(string a, int b = 0, int c = 1, string d)这样的东西肯定会在传递一个 int 时模棱两可。甚至可以通过首选表达式的类型来解决类似 double/int 组合的问题。(string a, int b = 0, string c, int d = 1, string e)仍然非常明确。一开始可能需要学习一些额外的东西,但我认为它会奏效。 -
我想指出,有时“命名参数习语”(C++ 常见问题解答)很有帮助。 只是有时,我不喜欢把它放在任何地方。但是你可以命名参数,这很酷。
标签: c++ default-arguments