2011-10-18 2 views
0

나는 templacised operator+= 함수를 작성하고 고유 한 네임 스페이스를 부여했습니다. (가끔씩 만 사용하기를 원합니다.템플릿 인스턴스화를위한 함수 내에 네임 스페이스 기호로드

그때 을 사용하고자하는 피연산자에 operator+=를 사용하는 다른 템플릿 함수 내부 기능,하지만 난 그게 내가 할 모든 단일 += 전화 덮쳐 대기 심볼 테이블에 주위를 어슬렁 떠나고 싶지 않아 내 프로그램 어디서나. 나는 또한 널리 포함되는 머리글 안에서 이것을해야한다.

이의 기본적인 예는이 결과를 얻을 수있는 방법이

#define BOOST_RESULT_OF_USE_DECLTYPE 

#include "boost\range.hpp" 
#include "boost\range\algorithm.hpp" 
#include <vector> 

using std::vector; 

namespace range_ops 
{ 
    template <class ForwardRange1, class SinglePassRange2> 
    inline ForwardRange1& operator+=(ForwardRange1& left, const SinglePassRange2& right) 
    { 
     auto left_it = boost::begin(left); 
     auto right_it = boost::begin(right); 
     for (; left_it != boost::end(left); ++left_it, ++right_it) 
      *left_it += *right_it; 

     return left; 
    } 
} 

template <class SinglePassRange, class Value> 
inline Value accumulate_increment(SinglePassRange& rng, Value val) 
{ 
    typedef typename boost::range_value<SinglePassRange>::type range_val; 
    boost::for_each(rng, [&](const range_val& x) { val += x; }); 
    return val; 
} 

template <class SinglePassRange> 
inline typename boost::range_value<SinglePassRange>::type accumulate_increment(SinglePassRange& rng) 
{ 
    return accumulate_increment(rng, typename boost::range_value<SinglePassRange>::type()); 
} 

//using range_ops::operator+=; // this works, but pollutes the global namespace with a templacised operator+= function - yuck! 
int main() 
{ 
    auto i = accumulate_increment(vector<int>(1)); // works fine 

    using range_ops::operator+=; // want this here, but accumulate_increment can't see the operator+= function 
    auto j = accumulate_increment(vector<vector<int>>(1)); 
} 

있습니까?

답변

0

증분 함수가 하나 밖에 없으므로 호출자에서 절을 사용하여 증분 함수 자체에 어떤 영향을 주길 기대합니까? 어떻게 operatior +를 찾겠습니까?

+1

템플릿 기능은 호출 사이트에서만 인스턴스화되기 때문에 함수를 처음 호출 할 때만 표시하면됩니다. 문제는 템플릿 함수가 처음 사용 된 실제 줄이 아니라 호출하는 함수의 시작에서 템플릿 함수가 인스턴스화된다는 것입니다. 따라서 함수 자체에서 선언을 사용하면 템플릿 함수가 인스턴스화 될 때 고려되지 않습니다. – Ayjay

+0

Ayjay - 내 약한 대답보다는 오히려 그 대답으로 게시해야합니다. –

+0

아, 대답이 아니므로, 왜 어려운지에 대한 설명입니다. 나는 그 주위에 방법이 있는지 묻고 싶다! – Ayjay

0

이 작업을 수행 할 수 있다고해도 나는 권장하지 않습니다. 여러분의 코드를 사용하는 누군가는 명시 적으로 전달되지 않은 외부 상태 (네임 스페이스 설정)에 의존하지 않는 객체의 내부 동작을 기대해야하며, 지리적으로 어디에 있는지에 따라 달라지지 않습니다 소스 파일에서).

연산자 오버로드는 이미 피연산자가 실제로 해당 연산자를 지원하지 않는 경우를 제외하고는 혼란스럽게 만드는 기능에 국한되어 있습니다.

이런 식으로 구현하려는 경우 멤버 SetOtherOperatorOverload (TRUE)와 같이 오버로드하는 연산자의 동작을 변경하는 개체의 상태를 설정해야합니다.