如何知道是传递了可选函数参数还是使用默认函数参数

How to know whether a optional function parameter was passed or is it using the default function parameter?

本文关键字:函数 参数 默认 何知道      更新时间:2023-10-16
void foo (  int arg1, int arg2)
foo(1)
foo(1,2)

我如何知道 int arg2 是使用像第二次 foo 调用那样传递的可选函数参数,还是像在第一次 foo 中那样使用默认函数参数?

更新:

公共:

头文件

// Point 1
void fireworkShipment(stack<Firework*>&);
void sellFireworks(stack<Firework*>&, int quantity);
// Point 2
void metalShipment(stack<Metal>&);
~FireworkFactory();
// Point 3 for correctness, Point 4 for O(1) runtime
void sellFireworks(stack<Firework*>&, int quantity, Color color);
void sellFireworks(stack<Firework*>&, int quantity); //error here

CPP 文件:

    void FireworkFactory::sellFireworks(stack<Firework*>& customerStack, int quantity, Color color){
    // TODO
    cout<< "which color: " << color << "n";
    for (int i = 0; i< fireworkstorage.size(); i++) {
        if (fireworkstorage.front()->getColor() == color && quantity != 0) {
            customerStack.push(fireworkstorage.front());
            cout<< "Color: " <<fireworkstorage.front()->getColor() << "n";
            fireworkstorage.pop();
            quantity--;
            cout<<  "Quantity: " <<quantity << "n";
        } else {
            fireworkstorage.push(fireworkstorage.front());
            fireworkstorage.pop();
        }
    }    
}
void FireworkFactory::sellFireworks(stack<Firework*>& customerStack, int quantity){
    for (int i = 0; i<quantity; i++) {
        customerStack.push(fireworkstorage.front());
        fireworkstorage.pop();
    }
}

你不能。但是,您可以使用一个参数创建重载函数:

#include <iostream>
void awesome_function_with_default_parameters(int arg1, int arg2 = 42)
{
    std::cout << "Doing some awesome work with " << arg1 << " and " << arg2 << std::endl;
}
void foo(int arg1, int arg2)
{
    std::cout << "Both parameters passed" << std::endl;
    awesome_function_with_default_parameters(arg1, arg2);
}
void foo(int arg1)
{
    std::cout << "Only one parameter passed" << std::endl;
    awesome_function_with_default_parameters(arg1);
}
int main()
{
    foo(1);
    foo(1, 314);
    return 0;
}

没有办法知道。如果foo(1)有效,则假定使用可选参数。

正如其他人已经指出的那样,没有办法判断是否使用了默认参数,或者是否显式指定了值。这是因为默认参数完全在编译时处理,而运行时的程序不知道它们。所以理论上你可以有

void myFunc(int a, int b = 42);

在标题和 CPP 中执行

void myFunc(int a, int b) {
  bool defaultParamUsed = (b ==42);
  // rest of function
}

但这意味着即使明确提供 42 的人也会被视为使用了默认参数。

只是为了让事情变得更加复杂,因为编译器处理默认参数,你可以通过为同一个函数签名提供不同的默认参数声明来很好地搬起石头砸自己的脚。在标题 a.h 中考虑:

void myFunc(int a, int b=42);

在标题 b.h 中:

void myFunc(int a, int b=70);

在实现文件 aMess.cpp:

void myFunc(int a, int b) // ...

如果 a.h 和 b.h 都包含在任何地方,编译器可能会(我很确定但还没有尝试过)抱怨(由于重复声明),但程序的不同部分可能包含不同的标头,因此使用不同的可选参数。
很难看出在什么情况下人们会想要这个。一种情况可能是表单的函数

void doSomething(int param, int version);

现在,不同的标头可以将不同的版本指定为默认值,并且用户仍然可以显式覆盖行为,以防他或她需要特定版本的行为。