【问题标题】:Loading namespace symbols inside a function for a template instantiation在函数内加载命名空间符号以进行模板实例化
【发布时间】:2011-10-18 01:56:14
【问题描述】:

我已经编写了一个模板化的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));
}

有没有办法达到这个效果?

【问题讨论】:

    标签: c++ templates boost namespaces boost-range


    【解决方案1】:

    只有 1 个增量函数,那么您如何期望您在调用者中使用子句来影响增量函数本身 - 它应该如何找到操作员+?

    【讨论】:

    • 因为模板函数只在调用点实例化,所以你只需要函数在你第一次调用的时候就可见。问题是,模板函数是在调用它们的函数的开头实例化的,而不是在第一次使用它们的实际行。因此,在实例化模板函数时,不考虑在函数内部使用声明。
    • Ayjay - 你应该把它作为答案发布 - 而不是我的弱回复
    • 哈哈,这不是一个答案,它是关于为什么它很难的描述。我想问问有没有办法解决这个问题!
    • 我不明白你想要做什么 - operator+ 参加了 2 节课。你能举一个更好的现实世界的例子来看看你真正想要做什么
    • 基本上,我已经编写了一个允许范围递增的模板函数。例如。 vector&lt;int&gt; x, y; x += y; 这是一个完全通用的函数,可以采用任何模拟 Boost 的 range 概念的东西。由于它的通用性,我不喜欢将它挂在符号表中,所以我将它包装在 range_ops 命名空间中。我还编写了一个自定义的accumulate 类函数,它在operator+= 之外运行,仅仅是因为这几乎总是我使用它的方式。我现在正在尝试将两者结合使用。
    【解决方案2】:

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

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

    如果你要实现这样的事情,你应该通过设置对象的状态来改变你重载的运算符的行为,例如成员 SetOtherOperatorOverload(TRUE);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-29
      • 1970-01-01
      • 1970-01-01
      • 2011-02-01
      • 2019-01-15
      相关资源
      最近更新 更多