好吧,令人困惑的问题。如果我有一个具有多个可选参数的函数或类构造函数(实际上只是一个特殊的函数),是否可以指定一个参数?例如:
float divide ( float a = 1.0, float b = 1.0 ) { return a / b; }
如何在不指定a的情况下指定b ?
P.S。我知道这个例子有些人为,但是到了重点。
答案 0 :(得分:1)
C ++中没有内置选项来命名调用中的特定参数(例如在Python中)。
可以使用辅助struct
来伪造此类命名参数。示例:
#include <iostream>
struct Denom {
float x;
Denom(float x): x(x) { }
};
struct Num {
float x;
Num(float x): x(x) { }
};
float divide(float a, float b) { return a / b; }
inline float divide(const Num &num) { return divide(num.x, 1.0f); }
inline float divide(const Denom &denom) { return divide(1.0f, denom.x); }
int main()
{
// regular call:
std::cout << "3 / 2: " << divide(3.0f, 2.0f) << '\n';
// call with numerator only:
std::cout << "3 / default: " << divide(Num(3.0f)) << '\n';
// call with denominator only:
std::cout << "default / 2: " << divide(Denom(2.0f)) << '\n';
// done
return 0;
}
输出:
3 / 2: 1.5
3 / default: 3
default / 2: 0.5
我记得,辅助struct
技巧甚至可以扩展为允许链接以及任意顺序的参数。搜寻“ C ++命名参数”,我在SO: C++ named arguments implementation with derived classes的答案之一中找到了另一个示例。示例:
#include <iostream>
struct Args {
float x, y;
Args(): x(1.0f), y(1.0f) { }
Args& num(float x) { this->x = x; return *this; }
Args& denom(float y) { this->y = y; return *this; }
};
float divide(float a, float b) { return a / b; }
float divide(const Args &args) { return divide(args.x, args.y); }
int main()
{
// regular call:
std::cout << "3 / 2: " << divide(3.0f, 2.0f) << '\n';
// call with numerator only:
std::cout << "3 / default: " << divide(Args().num(3.0f)) << '\n';
// call with denominator only:
std::cout << "default / 2: " << divide(Args().denom(2.0f)) << '\n';
// args in arbitrary order:
std::cout << "3 / 2: " << divide(Args().denom(2.0f).num(3.0f)) << '\n';
// done
return 0;
}
输出:
3 / 2: 1.5
3 / default: 3
default / 2: 0.5
3 / 2: 1.5
一次,我看到了gtkmm中的一个简单技巧,我会不时使用它自己–提供一个额外的enum
参数来消除歧义。示例:
#include <iostream>
enum ArgInitNum { InitNum };
enum ArgInitDenom { InitDenom };
float divide(float a, float b) { return a / b; }
inline float divide(ArgInitNum, float a) { return divide(a, 1.0f); }
inline float divide(ArgInitDenom, float b) { return divide(1.0f, b); }
int main()
{
// regular call:
std::cout << "3 / 2: " << divide(3.0f, 2.0f) << '\n';
// call with numerator only:
std::cout << "3 / default: " << divide(InitNum, 3.0f) << '\n';
// call with denominator only:
std::cout << "default / 2: " << divide(InitDenom, 2.0f) << '\n';
// done
return 0;
}
输出:
3 / 2: 1.5
3 / default: 3
default / 2: 0.5
注意:
对于简单的函数,我不会使用此技术,在简单函数中,您可以简单地使用不同的函数名。但是,这是消除构造函数歧义的不错选择。