缺少第一个构造函数参数
Missing the First Constructor Parameter
我有一个具有以下默认构造函数的 class 对象:
Point( double x = 0, double y = 0 );
如果我创建:
Point myPoint();
我会用 (0, 0)
加分。如果我创建:
Point mySecondPoint(14);
我会用 (14, 0)
加分。
但为什么是:
Point myThirdPoint(, 10) //invalid
不给我一分(0, 10)
。我应该如何编码以获得第二个参数而不是第一个参数的可能性?
因为C++有一些严格的句法规则。从这个角度来看,您的示例完全不正确。声明默认参数时,请遵循以下规则:您最不想更改的默认参数应该是最右边的默认参数,因为 C++ 要求在您要更改其默认值的参数之前指定所有参数。
与其他一些语言不同,C++
要求在提供参数之前提供所有默认参数。
来自 8.3.6 默认参数 [dcl.fct.default]
If an initializer-clause is specified in a parameter-declaration this
initializer-clause is used as a default argument. Default arguments
will be used in calls where trailing arguments are missing.
所以如果一个函数有 5 个参数,其中 3 个是默认参数:
- 默认 3 必须是最后 3 个参数
- 您可以使用前 2 个参数、前 3 个参数、前 4 个参数或所有 5 个参数调用函数。
How should I code for a possibility of having the 2nd parameter, but
not the first?
在我看来,您的构造函数接口不是很好。在这种情况下,我宁愿只有两个构造函数,默认没有任何参数,一个有两个参数。如果你只想给一个参数,你必须自己指定其他的默认值。
即
Point();
Point(double x, double y);
或者你应该使用一些函数来创建一个新点
Point CreateWithY(double y)
{
return Point(0.0, y);
}
并将其用作
Point p = CreateWithY(42.0); // Creates (0.0, 42.0)
不是答案的一部分但是:
Point myPoint();
声明一个 函数 myPoint,它不接受任何参数,return 一个 Point
类型的对象。您打算使用的可能是:
Point myPoint;
Point myThirdPoint(, 10) //invalid
正如其他人所说,C++ 不支持此语法。
How should I code for a possibility of having the 2nd parameter, but not the first?
首先你应该考虑这是否真的是应该做的。我不知道是否有更优雅的方法来实现这一点,但您可以引入新类型并依赖重载。 警告,我并不是建议你真的应该走这条路,而只是为了说明而展示。
struct X
{
X(double v = 0.0) : mValue(v) {}
operator double() const { return mValue; }
private:
double mValue;
};
struct Y
{
Y(double v = 0.0) : mValue(v) {}
operator double() const { return mValue; }
private:
double mValue;
};
class Point
{
public:
Point() : mX(0.0), mY(0.0) {}
Point(X x) : mX(x), mY(0.0) {}
Point(Y y) : mX(0.0), mY(y) {}
Point(X x, Y y) : mX(x), mY(y) {}
private:
double mX;
double mY;
};
int main()
{
Point p1;
Point p2(X(1));
Point p3(Y(2));
Point p4(X(3), Y(4));
return 0;
}
我有一个具有以下默认构造函数的 class 对象:
Point( double x = 0, double y = 0 );
如果我创建:
Point myPoint();
我会用 (0, 0)
加分。如果我创建:
Point mySecondPoint(14);
我会用 (14, 0)
加分。
但为什么是:
Point myThirdPoint(, 10) //invalid
不给我一分(0, 10)
。我应该如何编码以获得第二个参数而不是第一个参数的可能性?
因为C++有一些严格的句法规则。从这个角度来看,您的示例完全不正确。声明默认参数时,请遵循以下规则:您最不想更改的默认参数应该是最右边的默认参数,因为 C++ 要求在您要更改其默认值的参数之前指定所有参数。
与其他一些语言不同,C++
要求在提供参数之前提供所有默认参数。
来自 8.3.6 默认参数 [dcl.fct.default]
If an initializer-clause is specified in a parameter-declaration this initializer-clause is used as a default argument. Default arguments will be used in calls where trailing arguments are missing.
所以如果一个函数有 5 个参数,其中 3 个是默认参数:
- 默认 3 必须是最后 3 个参数
- 您可以使用前 2 个参数、前 3 个参数、前 4 个参数或所有 5 个参数调用函数。
How should I code for a possibility of having the 2nd parameter, but not the first?
在我看来,您的构造函数接口不是很好。在这种情况下,我宁愿只有两个构造函数,默认没有任何参数,一个有两个参数。如果你只想给一个参数,你必须自己指定其他的默认值。
即
Point();
Point(double x, double y);
或者你应该使用一些函数来创建一个新点
Point CreateWithY(double y)
{
return Point(0.0, y);
}
并将其用作
Point p = CreateWithY(42.0); // Creates (0.0, 42.0)
不是答案的一部分但是:
Point myPoint();
声明一个 函数 myPoint,它不接受任何参数,return 一个 Point
类型的对象。您打算使用的可能是:
Point myPoint;
Point myThirdPoint(, 10) //invalid
正如其他人所说,C++ 不支持此语法。
How should I code for a possibility of having the 2nd parameter, but not the first?
首先你应该考虑这是否真的是应该做的。我不知道是否有更优雅的方法来实现这一点,但您可以引入新类型并依赖重载。 警告,我并不是建议你真的应该走这条路,而只是为了说明而展示。
struct X
{
X(double v = 0.0) : mValue(v) {}
operator double() const { return mValue; }
private:
double mValue;
};
struct Y
{
Y(double v = 0.0) : mValue(v) {}
operator double() const { return mValue; }
private:
double mValue;
};
class Point
{
public:
Point() : mX(0.0), mY(0.0) {}
Point(X x) : mX(x), mY(0.0) {}
Point(Y y) : mX(0.0), mY(y) {}
Point(X x, Y y) : mX(x), mY(y) {}
private:
double mX;
double mY;
};
int main()
{
Point p1;
Point p2(X(1));
Point p3(Y(2));
Point p4(X(3), Y(4));
return 0;
}