繁体   English   中英

C ++ 11函数参数

[英]C++11 function parameters

是否有可能以某种方式使函数(C ++ 11)接受不同的参数取决于第一个? 可以说,我需要以下行为:

enum TypeFill{Solid, Gradient1, Gradient2};

void fill(const TypeFill t,  Type1 param1 = NULL, Type2 param2 = NULL){
  if (t == Solid){
       fillSolid(param1);
  } else if (t == Gradient1){
       fillGradient1(param1, param2);
  } else if (t == Gradient2){
       fillGradient2(param1, param2);
  }
}

private:
fillSolid(Brush b){};                
fillGradient1(Color c1, Color c2){};
fillGradient2(Color c1, Color c2){};

电话示例:

fill(Solid, Brush(1.0, 0.0, 0.0)){};                
fill(Gradient1, Color(1.0, 0.0, 0.0), Color(1.0, 1.0, 0.0)){};
fill(Gradient2, Color(1.0, 0.0, 0.0), Color(1.0, 1.0, 0.0)){};

只是想知道这是否可能。 我觉得这可能与enable_if和模板特化有关,但可能不是......

它归结为有几个重载,所以最简单的方法是定义:

  • fillSolid(Brush b)
  • fillGradient(Color c1, Color c2)

在这个设计中,你需要在每个特定的调用中在编译时知道枚举值,所以没有太大的收获。

OTOH你可能想重新设计你的代码,这样你就可以使用SolidGradient1Gradient2等不同的实现来实现Fill的实际抽象,而不是枚举,每个实现都有自己的数据集。


后续行动:这是您可以通过模板获得的语法示例:

fill<Solid>::call(Brush(1.0, 0.0, 0.0));               
fill<Gradient1>::call(Color(1.0, 0.0, 0.0), Color(1.0, 1.0, 0.0));
fill<Gradient2>::call(Color(1.0, 0.0, 0.0), Color(1.0, 1.0, 0.0));

枚举器现在是一个类模板参数,而不是函数参数,因此它在编译时解析,(成员)函数签名能够依赖它。

这里理智的是使用你直接拥有的三个功能。 如果你绝对必须有语法:

fill(Solid, Brush(1.0, 0.0, 0.0));
fill(Gradient1, Color(1.0, 0.0, 0.0), Color(1.0, 1.0, 0.0));
fill(Gradient2, Color(1.0, 0.0, 0.0), Color(1.0, 1.0, 0.0));

你可以从两个重载中得到它:

void fill(TypeFill t, Brush b) {
    assert(t == Solid);
    fillSolid(b);
}

void fill(TypeFill t, Color c1,  Color c2) {
  switch(t) {
  case Gradient1:
    fillGradient1(c1, c2);
    break;
  case Gradient2:
    fillGradient2(c1, c2);
    break;
  default:
    assert(false);
    break;
  }
}

如果你想要一个单独的功能足以抛出类型安全以及任何调试错误的可能性,你可以使用C风格的变量:

void fill(TypeFill t, ...) {
  va_list ap;
  va_start(ap, t);
  switch(t) {
  case Gradient1:
    fillGradient1(va_arg(ap, Color), va_arg(ap, Color));
    break;
  case Gradient2:
    fillGradient2(va_arg(ap, Color), va_arg(ap, Color));
    break;
  case Solid:
    fillSolid(va_arg(ap, Brush));
    break;
  default:
    assert(false);
    break;
  }
  va_end(ap);
}

请注意,不要像C ++11§5.2.2/ 7中详述的那样违反va_arg要求:

当给定参数没有参数时,参数的传递方式使得接收函数可以通过调用va_arg (18.10)来获取参数的值。 在参数表达式上执行左值到右值(4.1),数组到指针(4.2)和函数到指针(4.3)标准转换。 具有(可能是cv-qualified)类型std::nullptr_t将转换为void* (4.10)类型。 在这些转换之后,如果参数没有算术,枚举,指针,成员指针或类类型,则程序格式错误。 传递具有非平凡复制构造函数,非平凡移动构造函数或非平凡析构函数的类类型(第9章)的可能已评估的参数,没有相应的参数,通过实现定义的语义有条件地支持。 如果参数具有由积分促销(4.5)或浮点促销(4.6)限制的浮点类型的积分或枚举类型,则参数的值将在调用之前转换为提升类型。 这些促销被称为默认参数促销

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM