C++ 引用特定函数参数
好吧,这是个复杂的问题。如果我有一个具有多个可选参数的函数或类构造函数(实际上只是一个特殊函数),有没有办法指定一个参数而不是另一个参数?例如:C++ 引用特定函数参数,c++,function,arguments,C++,Function,Arguments,好吧,这是个复杂的问题。如果我有一个具有多个可选参数的函数或类构造函数(实际上只是一个特殊函数),有没有办法指定一个参数而不是另一个参数?例如: float divide(float a=1.0,float b=1.0){返回a/b;} 在不指定a的情况下,如何指定b S.I。这个例子有点做作,但它说到点子上。 < P> C++中没有内置的选项来命名调用中的特定参数(例如,在Python中)。 可以使用helperstructs伪造此类命名参数。例如: #include <iostream
float divide(float a=1.0,float b=1.0){返回a/b;}
在不指定a的情况下,如何指定b
S.I。这个例子有点做作,但它说到点子上。
< P> C++中没有内置的选项来命名调用中的特定参数(例如,在Python中)。 可以使用helperstruct
s伪造此类命名参数。例如:
#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;
}
#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;
}
#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;
}
我记得helper
struct
技巧甚至可以扩展为允许链接和任意顺序的参数。在谷歌上搜索“C++命名参数”,我在其中一个答案中找到了另一个例子。例如:
#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;
}
#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;
}
#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;
}
有一次,我在gtkmm中看到了一个我经常使用的简单技巧——提供了一个额外的
enum
参数来消除歧义。例如:
#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;
}
#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;
}
#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;
}
注:
我不会在简单的函数中使用这种技术,因为你可以简单地使用不同的函数名。但是,消除构造函数的歧义是一个很好的选择。如果函数参数的类型不同,不能相互转换,可以使用适当的重载。否则这是不可能的。考虑:为了让你的问题有意义,假设
result=divide(3.0f)
,你希望一个人如何计算3.0f
是a
还是b
的值?更不用说编译器了?我当前的用例与类的可选输入和输出文件名有关。有时,我想让一个类从文件中读取数据,然后在屏幕上打印一些结束计算。其他时候,我希望它获取一组给定的数字,并将计算结果记录到一个文件中。由于两个文件名都是字符串,我不知道如何处理这个问题。如果您试图自己处理它(不同于期望编译器解决您未声明的意图),您将如何决定需要什么操作?重载函数。这是唯一的方法。请看,它旨在将命名参数引入C++。