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中)。

可以使用helper
struct
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++。