Loading namespace symbols inside a function for a template instantiation

116 views Asked by At

I have written a templacised operator+= function and given it a unique namespace (I only want to use it sometimes, and this allows me to exlpicitly).

I would like to then use that function inside another template function that uses operator+= on its operands, but I don't want to leave it hanging around in the symbol table waiting to pounce on every single += call I do anywhere in my program. I also have to do this inside a header that is widely included.

A basic example of this is:

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

Is there any way to achieve this result?

2

There are 2 answers

7
Adrian Cornish On

There is only 1 increment function so how did you expect you using clause in the caller to affect the increment function itself - how is it supposed to find operatior+?

0
MartyTPS On

Even if you could do this I would not recommend it. Someone using your code should expect an object's internal behavior to not depend on some external state (your setting of the namespace) that is not explicitly passed into it and doesn't move around with it (not something that depends on where is it geographically sitting in a source file).

Operator overloading is already a feature that borders on making things confusing except in cases where the operands are things that normally would not support that operator in nature.

If you were to implement something like this, you should do it by setting state of the object that changes the behavior of the operator you overload, such as a member SetOtherOperatorOverload(TRUE);