在函数内加载命名空间符号以进行模板实例化

发布于 2024-12-10 04:34:59 字数 1789 浏览 0 评论 0原文

我编写了一个模板化的operator+=函数,并给它一个唯一的命名空间(我只想有时使用它,这让我可以明确地使用它)。

然后我想在另一个模板函数中使用 that 函数,该函数在其操作数上使用 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));
}

有什么办法可以达到这个结果吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

滥情空心 2024-12-17 04:35:00

即使你能做到这一点我也不会推荐它。使用您的代码的人应该期望对象的内部行为不依赖于某些未显式传递给它的外部状态(您对命名空间的设置),并且不会随其移动(不依赖于它的地理位置)在源文件中)。

运算符重载已经是一种使事情变得混乱的功能,除非操作数本质上通常不支持该运算符。

如果要实现类似的功能,则应该通过设置对象的状态来更改重载运算符的行为,例如成员 SetOtherOperatorOverload(TRUE);

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

木格 2024-12-17 04:34:59

只有 1 个增量函数,所以您如何期望调用者中的 using 子句影响增量函数本身 - 它应该如何找到 operatior+?

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+?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文