2013-07-25 11 views
1

foo()operator<<()으로 변경하려고합니다. C++과 비슷한 모양의 "half C/half C++"코드를 얻기 위해서입니다.Variadic 템플릿 연산자 <<

template <class... T> 
inline const size_t foo(const T&... data) { 
    return sizeof...(T); 
} 
struct bar { 
    template <class... T> 
    inline const size_t operator<<(const T&... data) { 
     return sizeof...(T); 
    } 
}; 
int main(int argc, char *argv[]) { 
    bar a; 
    std::cout << ">>> length " << foo(1, 2, 3) << std::endl; 
    std::cout << ">>> length " << (a << 1 << 2) << std::endl; 
    std::cout << ">>> length " << (a << 1 << 2 << 3) << std::endl; 
    std::cout << ">>> length " << (a << 1 << 2 << 3 << 4) << std::endl; 
} 

출력에서 ​​:

$ ./a.out 
>>> length 3 
>>> length 4 
>>> length 32 
>>> length 512 

제가 제 계산이 a << 1 따라 수행 체결하고, 후속 값은, 그러나, I는 다음 변환 단계에 붙어있어 한도 일어나지 그에 따라 시프트. 그러나 foo()을 다시 쓰지 않고, 의미를 변경하지 않고 struct bar의 사용자에게 operator<<() 인터페이스을 제공하는 방법을 알지 못합니다.

operator<<()class T...을 매개 변수로 전달할 방법이없는 경우이 함수는 여러 번 호출되기 때문에 자연히 foo()보다 효율적이지 않습니다. 이것에 대한 합리적인 C++ 구조가 있습니까? 아니면 foo()을 고집하는 것이 유일한/최선의 선택입니까?

컨텍스트 :

foo() 이러한 기능은 통신 네트워크에 발신자/수신자이다. 나는 <<>> 연산자를 사용하여 쓰기/읽기가 가능한 발신자/수신자 스트림을 사용하여 일반 "foo(...)"이외의 "C++"인터페이스를 제공하는 것이 더 좋을 것이라고 생각했습니다.

+2

"C + -code"란 무엇입니까? 이상한 구조, 절반 C, 하프 프로그래밍 언어? –

+0

질문에 올바르게 대답하려면이 각각이 실제로 무엇을하고 있습니까? – chris

+0

@chris 문제에 * context *를 추가했습니다. 그 질문을 분명히하기를 바랍니다. – Rubens

답변

3

언어가하고있는 일을하고 있습니다. 연관성

, 다음은 동일합니다 (<<>> 있습니다 왼쪽에서 오른쪽으로 결합) :

a << 1 << 2 
(a << 1) << 2 

a << 1가 차례로 size_t 반환하는 사용자 정의 연산자를 호출하는 전화. 그래서 다음 호출의 유형은 다음과 같습니다 : size_t << int (간단한 비트 시프트입니다).

표현 템플릿을 사용해야합니다. 아이디어는 다음 (live example here)입니다 :

template<typename... args> 
struct stream_op 
{ 
}; 

template<typename... A, typename B> 
stream_op<A..., B> operator<<(stream_op<A...> a, B b) 
{ 
    // Do stuff 
} 

그래서,이 (astream_op<> A와 함께) 발생 다음 :

a << 1 << 2 
------ 
    | 
    v 
------------------------------------------- 
stream_op<int> operator<<(stream_op<>, int) << 2 
--------------        --- 
    |           | 
    |    +---------------------------+ 
    v    v 
-------------- --- 
stream_op<int> << int 
-------------- --- 
     |   | 
     |   +---------------------------+ 
     +----------------------------+   | 
            v   v 
           -------------- --- 
stream_op<int,int> operator<<(stream_op<int>, int) 
------------------ 
     | 
     v 
------------------ 
stream_op<int,int> // <- Expected result 

그런 다음 당신은 단지에 stream_op를 변환하는 방법을 넣어야 int (또는 원하는대로).

성능에 대한 참고 사항 : 이러한 표현 템플릿을 사용하면 데이터의 일부가 형식으로 인코딩되므로 일반적으로 foo(...)에 대한 직접 호출만큼 빠릅니다.

+0

아주 좋은 해결책! 내 응용 프로그램에서 사용하려고합니다. 감사! – Rubens