Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何将类似运算符的表达式声明为函数调用?_C++ - Fatal编程技术网

C++ 如何将类似运算符的表达式声明为函数调用?

C++ 如何将类似运算符的表达式声明为函数调用?,c++,C++,目标: 描述一种提供函数调用的方法,即对于给定函数T FT a,T b,代码中以aEb形式编写的表达式E将函数调用为Fa,b 动机: 提供函数调用的缩写形式,当特定语法与标准形式相比会提高代码的清晰度时 例如: 我真的不想使用的可能解决方案: 1运算符重载函数对象,如下所述 将每个外观调用的真函数调用数增加三倍 相关问题: 以语法为“x=M[row][column]”的矩阵形式访问一维数组M。 有必要为两类不同的对象定义运算符[]的两个重载:矩阵和向量(行或列)。 一个'M[row][colum

目标:

描述一种提供函数调用的方法,即对于给定函数T FT a,T b,代码中以aEb形式编写的表达式E将函数调用为Fa,b

动机:

提供函数调用的缩写形式,当特定语法与标准形式相比会提高代码的清晰度时

例如:

我真的不想使用的可能解决方案:

1运算符重载函数对象,如下所述

将每个外观调用的真函数调用数增加三倍

相关问题:

以语法为“x=M[row][column]”的矩阵形式访问一维数组M。 有必要为两类不同的对象定义运算符[]的两个重载:矩阵和向量(行或列)。 一个'M[row][column]'调用然后从M[row]创建一个匿名向量,在该向量上执行[column]。 ... 然后,每一个“M[row]”调用都会从构造函数生成一个对象,在该构造函数上它自己的成员函数运算符[]只被调用一次,然后它将被立即丢弃

在准数学表示法中使用矩阵运算:

class Matrix
{
  Matrix invert();
  Matrix transpose();
};

Matrix m;
// m = m.invert();
m = m^-1;    // Assuming here that the whole "^-1" were the call sign.
m = m sup-1; // Assuming here that the whole "sup-1" were the call sign.
// m = m.transpose();
m = m^T;    // Dito here; the 'T' is not supposed to be a separate Token.
m = m supT; // This should work in spite of operator^, as it would not be defined for a custom Matrix class.
隐藏对象的封装:

class Value
{
  member x;
};
class EncapsulatedValue<Value T>
{
  T value;

  EncapsulatedValue(T value) : value{value}
  {}

  member x()
  {
    member y = T.x;
    /* modifies y */
    return y;
  }
};

Value temp;
EncapsulatedValue v(temp);
member z;
// z = v.x();
z = v.x;

不能在内置类型或原始指针的参数上重载运算符

除此之外,你几乎可以自由地做任何你想做的事


问题是什么?

这只是一个部分答案,但也许可以通过额外的投入加以改进。 雅克和sp2danny的指点让我走了这么远

通过以下方式定义用户文字,可以部分解决骰子示例:

unsigned int operator"" d6(unsigned long long int number)
{
  return operatorD(number, 6u);
}
显然,operatorD可以完全在这个文本定义中实现,因此满足了不引入额外运行时开销的要求

这实际上可以称为:

unsigned int x = 4 + 3d6;
但是请注意,当操作符名称不以下划线开头时,g++将抛出一个警告,所有没有前缀的名称都由标准化委员会保留

缺少的部分在于必须将运算符的第二个参数,即要抛出的骰子的边,编码到文字标签中,即:明确地定义所有可用的骰子作为文字

两边都有变量的实现,如运算符+,似乎不可能使用这种技术:

unsigned int operator"" d(unsigned long long int number, unsigned long long int sides) // Parameters like on operator+
{
  return operatorD(number, sides);
}
// error: [...] has invalid argument list
正如定义前缀而不是后缀似乎不是:

unsigned int operator"" d(unsigned long long int size, int) // Parameters like on postfix operator++
{
  return operatorD(1, size);
}
// same error
// Comparing the d6 variant with operator++ signature already provided a dead giveaway:
// The postfix operator++ has the spoof parameter, the postfix user literal does not.
有趣的是,使用所演示的可变模板确实应该允许定义具有任意数量参数的后序运算符

要完全解决此示例,仍然需要生成一个适用于任意多个面的代码,以便编写例如3d13不会突然失败,因为之前没有明确声明d13后缀

上述但未解释的第一个矩阵示例可通过使用表达式模板和运算符[]的重载(如所述)独立于此进行求解

其他提到的矩阵示例可以使用单个用户定义的后缀来解决:

Matrix operator"" T(Matrix & m)
{
  return m.transpose();
}
如果只能为类定义用户文字,而不仅仅是为原语定义用户文字

到目前为止,四分之一的人;最好的例子至少部分解决了。。。
但肯定可以做得更好

解决矩阵[a][b]问题的代码太长,无法在注释中发布,但我可以说,我可以为每个矩阵[a]调用保存一个类定义、三个运算符重载和一个对象实例化,只要有办法告诉我“m[a][b]”应该是指“m.ata,b”,其中m是矩阵和a类型,b是整数。也许你可以做一个原始文字?对于3,你说每一个真正的函数调用有3个函数调用。这是因为你害怕性能受到影响吗?视情况而定。以骰子为例,我毫不在乎。然而,当矩阵变得足够大并且在其上运行了足够多的操作时,矩阵示例确实会遭受显著的性能损失,就像在高维聚酯上进行单纯形搜索一样。一般来说,由于这主要是一个虚荣的特性,我准备在编写代码方面进行大量额外的工作,但是引入额外的计算负载是不值得的。想想看:如果你可以写M[A] [B],但M.ATA,B将保证至少三倍快…你想写m[a][b]吗?问题是:如何使int x=1+1d6;一个可编译语句,等于int x=1+operatorD1,6。。。有一些限制,例如不引入几个假类、创建假对象以及在运行时进行大量辅助函数调用。@匿名投票人:请解释一下您认为这个答案有什么错误。@Zsar:这些要求听起来非常主观。猜猜看,只有你自己才能满意地回答你的问题。[…]你可以自由地做任何你想做的事
蚂蚁显然是错误的,正如我在OP中提到的,运算符定义不是C++的固有特性——只对现有操作符进行重载。如果这有什么不同的话,我的第一个例子甚至可以按原样工作——那么毫无疑问。。。顺便说一句,我没有投反对票,只是分享了我的看法。@Zsar:你可以做任何你想做的事情,只要你正确地说出你的操作员。1+1d6不能工作,但1+1*d*6可以作为运算符+1,D1,6进行评估
unsigned int operator"" d(unsigned long long int size, int) // Parameters like on postfix operator++
{
  return operatorD(1, size);
}
// same error
// Comparing the d6 variant with operator++ signature already provided a dead giveaway:
// The postfix operator++ has the spoof parameter, the postfix user literal does not.
Matrix operator"" T(Matrix & m)
{
  return m.transpose();
}