15

다음 구조체 고려 과부하 콤마 연산자 (연산자)과 불가 (?)공극(),

struct S {}; 

C++ (14)는, 정의는 다음 유효 :

constexpr auto f() { return S{}, 'c'; } 

뿐만 아니라 다음과 같은 하나 :

이제
constexpr auto f() { return S{}, void(); } 

, 두 정의의 첫 번째 포함 다음, 작업 조각을 고려 :

#include<type_traits> 

struct S {}; 

constexpr int operator,(S, char) { return 42; } 
constexpr auto f() { return S{}, 'c'; } 

int main() { 
    constexpr int i{f()}; 
    static_assert(i == 42, "!"); 
    static_assert(std::is_same<decltype(f()), int>::value, "!"); 
} 

때문에 기술적으로 말하기뿐만 올바르게 main 기능에 확인 쉼표 연산자 차단 부부 S{}, 'c' 및 정수를 반환의 과부하.

지금, 나는 f의 두 번째 정의와 동일한 기능을 수행한다고 가정 :이 경우

constexpr auto f() { return S{}, void(); } 

, 쉼표 연산자해야 차단 형태 S{}, void(). (분명한 이유)
어느 다음과 같은 정의의 작품 :

constexpr int operator,(S, void) { return 42; } 

아니다 아래와 (즉, 앞의 경우에서 일 것이다) : 쉼표를 오버로드 할 수있는 방법은

template<typename T> constexpr int operator,(S, T &&) { return 42; } 

있는가 연산자로 S{}, void()을 처리할까요?
쉼표 연산자를 그런 식으로 사용할 수 있기 때문에 표준에 부족하지 않습니까? (the standard mentions that overloaded functions involving S are allowed과 같은 경우에도) 동일한 연산자에 과부하가 걸리지는 않습니까?


:이 질문에 호기심을 위해 이루어진다. 제발, 같은 코멘트를 피하십시오 또는 그것은 좋은 연습하지 않습니다. 프로덕션 환경에서는 그렇게 할 계획이 아닙니다. 고맙습니다.

+2

그것은 매우 흥미 롭군요.) –

+0

@JesperJuhl 예, 알고 있습니다. 표준 게릴라. 나는 언어의 가장 모호한 모퉁이를 탐험하고있다. :-) – skypjack

+0

연산자','를'+'로 변경하면 "인수가 'void'유형"오류를 가질 수 없습니다. – kennytm

답변

20

이에 대한 중요한 절 N4140에 13.3.1.2/9 [over.match.oper]이다 조작자가 조작 , 단항 연산자 & 또는 오퍼레이터 ->이다

하면 어떠한 실행 가능한 기능 후 조작자가 void() 5.

유효한 함수 인수 결코 항에있어서, 운전자에 내장 해석 (참조로 가정 5.2.2/7 EXPR은 없다 . 콜]), 거기에 ver는 실행 가능한 함수이므로 내장 된 ,이 사용됩니다.

아니, 당신이하려는 것은 불가능합니다.이

for(...; ++it1, (void)++it2) 

같은 반복자 루프를 작성 사실

는 내장 연산자 , 사용하도록 강제함으로써 반복자 유형에 대한 ,를 오버로드하여 코드를 파괴하지 못하도록하는 표준 방법입니다. (나는 당신이 당신의 일상 코드에서이 작업을 수행 할 필요가 말하고 있지 않다 있습니다 그것은 매우 실제 사용에 따라이 편집증의 표준 라이브러리 수준입니다...)


를 사용하면 링크 된 표준 조항과 관련하여 :

각 유형에 대해 미리 정의

오퍼레이터 =의 의미 (단항) &와, (쉼표)이 작업자 구현 연산자 함수를 정의하여 특정 클래스 및 열거 타입 위해 변경 될 수있다.

그러나 위에서 설명한 것처럼 void()은 절대로 유효한 함수 인수가 아니기 때문에 이러한 함수를 정의 할 수 없습니다.

표준의 감독/문제인지 여부는 이제 논쟁의 여지가 있습니다.

+2

오버로드 된 쉼표 호출을 피하기 위해 루프에서'(void)'를 흥미롭게 사용. 팁 고마워! – paulotorrens