2017-05-05 10 views
1

저는 여가 시간에 C++에 대해 배우고 있으며 하위 클래스/[] 연산자를 오버로드하는 클래스를 구현하고 있습니다.연산자 오버로드 컨텍스트 특정 만들기

myObject[i,j,...], 인수가 예를 들어 string의 또는 int

내가 볼 수 있습니다 : 지금, 나는 첨자 연산자를 다음과 같이 (쉼표로 구분)에 두 개 이상의 인수를 전달 할 수 있기를 원 C++에서는 subscript 연산자가 하나 이상의 인수를 허용하지 않는다. 그러나 '문제'에 대한 대안으로 this thread에 쉼표 연산자를 오버로드하는 방법에 대해 읽었습니다.

예에서 쉼표 연산자는 두 개의 사용자 지정 Enum과 함께 매우 구체적인 서명을 사용하여 오버로드되지만 일반적인 유형 쌍에 대해 쉼표 연산자를 오버로드하는 것은 좋지 않습니다. 케이스).

C++에 대한 제한된 지식으로 인해 '범위'또는 쉼표 연산자 오버로드를 특정 상황이나 상황 (예 : 첨자 연산자에서만 사용)으로 제한 할 수 있는지 여부가 궁금합니다. 과부하 정의, 다른 곳에서는 간섭을 일으키지 않고 관심있는 기능을 제공합니다.

답변

1

일반 함수/연산자를 컨텍스트로 제한 할 수는 없지만 네임 스페이스 덕분에 범위를 제한 할 수 있습니다. 대안으로

Demo

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); 
    } 
} 

, 당신은 일반적인 방법을 사용할 수있다, (여러 매개 변수를 취할 수 있습니다) 인수로 std::pair/ std::tuple를 사용 operator() 방법 (즉, 호출 사이트에서 {}를 둘러싸는 별도 필요).

+0

이것은 멋집니다! 고마워. 따라서 네임 스페이스를 사용하여 이론적으로 예를 들어 'std :: pair 연산자, (int lhs, int rhs) {return {lhs, rhs}; }'그 범위 내에서, 쉼표 연산자의 다른 용도를 망가 뜨리지 않고, 그 범위 밖에서, 맞습니까? – TBZ92

+0

'연산자,'클래스 또는 열거 형의 매개 변수가 하나 이상 있어야합니다. 'int' /'int'는 불법입니다. – Jarod42

0

아니요 특정 컨텍스트에만 운영자를 오버로드 할 수 없습니다. 너는 그대 운영자의 유형에 기초하여 그 사용을 여전히 제한 할 수있다.

0

연산자를 오버로드하면이 연산자와 함께 사용할 수있는 형식이 지정됩니다. 따라서 클래스 내에 정의 된 유형으로 디자인하는 것이 좋습니다.

class YourClass 
{ 
public: 
class YourType{}; 
}; 

pair<YourClass::YourType, YourClass::YourType> operator , (YourClass::YourType p1, YourClass::YourType p2) 
{ 
    return make_pair(p1, p2); 
} 

그러나 일반화가 필요한 경우 템플릿과 템플릿 전문화를 사용할 수 있습니다.

+0

예,이 또한 내 질문에 연결된 예제를 제공합니다. 나는 일반적인 유형의 논증에 대해 안전하게 수행 할 수 있는지 여부를 궁금해하고 있었지만 이것이 가능하지 않다고 생각합니다. – TBZ92