Загрузка символов пространства имен внутри функции для создания шаблона
Я написал темплацированный 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));
}
Есть ли способ достичь этого результата?
2 ответа
Даже если бы ты мог сделать это, я не рекомендовал бы это. Кто-то, использующий ваш код, должен ожидать, что внутреннее поведение объекта не будет зависеть от какого-то внешнего состояния (вашей установки пространства имен), которое явно не передается в него и не перемещается вместе с ним (не то, что зависит от того, где он находится географически). в исходном файле).
Перегрузка операторов уже является функцией, которая граничит с путаницей, за исключением случаев, когда операнды - это вещи, которые обычно не поддерживают этот оператор по своей природе.
Если вы хотите реализовать что-то подобное, вы должны сделать это, установив состояние объекта, который изменяет поведение оператора, который вы перегружаете, например, член SetOtherOperatorOverload(TRUE);
Существует только 1 функция приращения, так как вы ожидали, что использование выражения в вызывающей стороне повлияет на саму функцию приращения - как это должно найти operatior+?