使运算符重载上下文特定
Making an Operator Overload context specific
业余时间学习C++,正在实现一个重载下标/[]
运算符的class。现在,我希望能够将两个或多个参数传递给下标运算符,如下所示(用逗号分隔):
myObject[i,j,...]
,其中参数可以是 string
s 或 int
s
我发现C++不允许下标运算符接受一个以上的参数。但是,我读到了有关在 this thread 中重载逗号运算符的信息,作为 'problem'.
的替代解决方案
在示例中,逗号运算符使用非常具体的签名重载,有两个自定义 Enum
,但我可以看到为一般类型对重载逗号运算符不是一个好主意 (这将是我的用例)。
由于我对 C++ 的了解有限,这让我很好奇是否完全有可能将 'scope' 或逗号运算符重载的使用限制在特定情况或上下文中,例如,仅在下标运算符重载定义,为我提供我感兴趣的功能,而不会在其他地方造成干扰。
不可以仅针对特定上下文重载运算符。您仍然可以根据您的运营商类型限制其使用。
当您重载一个运算符时,您就是在指定哪些类型可以与该运算符一起使用。因此,使用 class 中定义的类型来设计它是个好主意。
class YourClass
{
public:
class YourType{};
};
pair<YourClass::YourType, YourClass::YourType> operator , (YourClass::YourType p1, YourClass::YourType p2)
{
return make_pair(p1, p2);
}
但是如果您需要某种形式的泛化,您可以使用模板和模板专业化。
您不能将常规 function/operator 限制为上下文,但您可以通过命名空间对其进行范围限制。
enum class E {A, B};
struct C
{
int operator [](const std::pair<E, E>& p) const
{
return data[static_cast<int>(p.first) * 2 + static_cast<int>(p.second)];
}
std::array<int, 4> data{{1, 2, 3, 4}};
};
namespace comma
{
std::pair<E, E> operator , (E lhs, E rhs) { return { lhs, rhs }; }
}
int main()
{
C c;
{
using namespace comma; // operator , is valid here.
std::cout << c[E::A, E::B] << std::endl;
auto p = (E::A, E::B); // but also here :/ p = {E::A, E::B}
static_cast<void>(p);
}
{
std::cout << c[E::A, E::B] << std::endl; // result in c[E::B]
auto p = (E::A, E::B); // p = E::B
static_cast<void>(p);
}
}
作为替代方案,您可以使用常规方法,operator ()
方法(可以采用多个参数),使用 std::pair
/std::tuple
作为参数(这需要额外的封闭 {}
在呼叫站点)。
业余时间学习C++,正在实现一个重载下标/[]
运算符的class。现在,我希望能够将两个或多个参数传递给下标运算符,如下所示(用逗号分隔):
myObject[i,j,...]
,其中参数可以是 string
s 或 int
s
我发现C++不允许下标运算符接受一个以上的参数。但是,我读到了有关在 this thread 中重载逗号运算符的信息,作为 'problem'.
的替代解决方案在示例中,逗号运算符使用非常具体的签名重载,有两个自定义 Enum
,但我可以看到为一般类型对重载逗号运算符不是一个好主意 (这将是我的用例)。
由于我对 C++ 的了解有限,这让我很好奇是否完全有可能将 'scope' 或逗号运算符重载的使用限制在特定情况或上下文中,例如,仅在下标运算符重载定义,为我提供我感兴趣的功能,而不会在其他地方造成干扰。
不可以仅针对特定上下文重载运算符。您仍然可以根据您的运营商类型限制其使用。
当您重载一个运算符时,您就是在指定哪些类型可以与该运算符一起使用。因此,使用 class 中定义的类型来设计它是个好主意。
class YourClass
{
public:
class YourType{};
};
pair<YourClass::YourType, YourClass::YourType> operator , (YourClass::YourType p1, YourClass::YourType p2)
{
return make_pair(p1, p2);
}
但是如果您需要某种形式的泛化,您可以使用模板和模板专业化。
您不能将常规 function/operator 限制为上下文,但您可以通过命名空间对其进行范围限制。
enum class E {A, B};
struct C
{
int operator [](const std::pair<E, E>& p) const
{
return data[static_cast<int>(p.first) * 2 + static_cast<int>(p.second)];
}
std::array<int, 4> data{{1, 2, 3, 4}};
};
namespace comma
{
std::pair<E, E> operator , (E lhs, E rhs) { return { lhs, rhs }; }
}
int main()
{
C c;
{
using namespace comma; // operator , is valid here.
std::cout << c[E::A, E::B] << std::endl;
auto p = (E::A, E::B); // but also here :/ p = {E::A, E::B}
static_cast<void>(p);
}
{
std::cout << c[E::A, E::B] << std::endl; // result in c[E::B]
auto p = (E::A, E::B); // p = E::B
static_cast<void>(p);
}
}
作为替代方案,您可以使用常规方法,operator ()
方法(可以采用多个参数),使用 std::pair
/std::tuple
作为参数(这需要额外的封闭 {}
在呼叫站点)。