2017-02-16 7 views
0

클래스가 있으므로 가변 인수 템플릿 인수로 Sample이라고합시다. 이 클래스에는 run(Args... args) 함수가 포함되어 있습니다. 이 클래스는 또한이 함수를 호출하는 스트림 연산자를 구현합니다.스트림 연산자에 여러 인수 전달

클래스는 다음과 같습니다 : 내가 아는

void main() 
{ 
    Sample<int, string, int> s; 

    // doesn't work :(
    s << {1, "msg", 2} << {1, "msg", 2}; 
} 

:

template<typename ...Args> 
class Sample 
{ 
    void run(Args... args) 
    { 
     // do something 
    } 

    Sample& operator<<(const tuple<Args...>& args) 
    { 
     run(unpack_somehow(args)...); 
     return *this; 
    } 
}; 

가 지금은 튜플의 중괄호 초기화를 통해 인수를 전달하여, 다수의 호출을 CONCAT하는 스트림 연산자를 사용하려면 나는 단지 make_tuple(1, "msg", 2)을 쓸 수 있으며 작동 할 것이지만, make_tuple과 같은 추가 함수 호출을 필요로하지 않는 솔루션을 찾고 있습니다.

인수를 중괄호로 전달할 수있는 기능을 구현할 수 있습니까 (또는 쉼표 분리 연산자로 쉼표 연산자를 오버로드 할 수 있습니까?)?

+5

중괄호 초기화 목록은 표현식이 아닙니다. . '<<'연산자가 그 지점들 중 하나가 아니기 때문에 문법에 몇 가지 특정 지점이 나타납니다 (예 : 함수 호출의 인수로, return 문에서). 표시하는 구문은 C++이 아니므로 작동하지 않을 수 있습니다. –

+1

@IgorTandetnik -이 경우 귀찮은 것은 결국 * 함수 호출이라는 것입니다. – StoryTeller

+3

's.run (1, "msg", 2) .run (1, "msg", 2); 그냥'run'이'this'에 대한 참조를 리턴하도록하십시오. 구체적으로 operator <<가되어야합니까? –

답변

2

s << {1, "msg", 2} << {1, "msg", 2}; 라인을 사용할 때 C++ 컴파일러는 이니셜 라이저 목록의 의미를 추론하는 데 충분한 정보를 제공하지 않습니다.

컴파일러에 힌트를주고 (make_tuple을 사용하거나 실제 tuple 변수를 전달하지 않는 한) 어떤 의미인지 알 수 없으므로 적절한 operator<<()을 호출 할 수 없습니다.

운이 좋지 않은 것처럼 보입니다. 귀하의 질문이 게시되는 방식으로는이 작업을 수행 할 수 없습니다.

+0

다음의 구현을 변경할 수 있다고 가정 해 봅시다. 'Sample :: run'. 어떻게 작동하도록 코드를 수정해야합니까? – Timo

+0

's.operator << ({1, "msg", 2})'가 작동하기 때문에 좋은 이유는 아닙니다. 문제는 initializer_list를 연산자의 왼쪽/오른쪽으로 사용할 수 없다는 것입니다. – Jarod42

1

운영자 측에서 초기화 프로그램 목록을 사용할 수 없습니다.

왼쪽에서는 사용할 수 없으므로 왼쪽에서는 사용할 수 없으므로 왼쪽에서 사용할 수 없으므로 왼쪽에서 사용할 수 없으며, 왼쪽에서는 사용할 수 없으므로 오른쪽에서는 사용할 수 없습니다. 이에 대한 이유에 관해서는

, 2007 스트로브 스트 룹과 도스 헤이스에 의한 draft/discussion paper N2215는 다양한 상황에서 초기화-목록과 많은 문제에 대한 통찰력을 많이 제공합니다. 특히, 이진 연산자 (섹션 6.2)에 대한 섹션이 있습니다.

이니셜 라이저 목록의보다 일반적인 사용을 고려하십시오. 예를 들어 :

v = v+{3,4}; 
v = {6,7}+v; 

우리가 기능을위한 문법 설탕 등의 연산자를 고려

, 우리는 자연스럽게

v = operator+(v,{3,4}); 
v = operator+({6,7},v); 

표현에 초기화 목록의 사용을 확장하는 것이 자연에 위 상당을 고려하십시오. 연산자와 결합 된 이니셜 라이저 목록이 "자연스러운"표기법 인 많은 용도가 있습니다.
그러나 이니셜 라이저 목록을 임의로 사용할 수있는 LR (1) 문법을 작성하는 것은 쉽지 않습니다. 또한 블록은 {로 시작하여 표현식의 첫 번째 (가장 왼쪽) 엔티티가 문법에서 혼란을 일으킬 수 있으므로 이니셜 라이저 목록을 허용합니다.
바이너리 연산자의 오른손 피연산자로 이니셜 라이저 목록을 허용하려면 하위 문법 및 유사한 문법 부분을 사용하는 것이 중요합니다. 실제 문제는 ;{1,2}+b;도 허용하지 않고 ;a={1,2}+b;을 할당 문으로 허용하는 것입니다.대부분의 연산자에 대한 이니셜 라이저 목록을 왼손 인수로 허용하는 것이 너무 많은 실수라고 생각합니다. [...]