在不同的命名空间中使用模板

时间:2014-05-17 16:28:48

标签: c++ templates namespaces

我不确定确切的问题,但是这段代码:

template<class T>
inline std::ostream& operator <<(std::ostream& ss, std::vector<T> const& vec)
{
    auto it(begin(vec));
    if (it != end(vec))
        ss << *(it++);
    for (; it != end(vec); ++it)
        ss << " " << *it;
    return ss;
}
如果

与我尝试使用它的地方位于同一名称空间中,

就会被选中。

如果它不同,则无法找到它。

为什么?有一个简单的解决方案吗?一个using?一个::

2 个答案:

答案 0 :(得分:2)

根据您在评论中发布的code,我看到了以下解决方案:

#include <iostream>
#include <vector>

template<class T>
inline std::ostream& operator <<(std::ostream& ss, std::vector<T> const& vec)
{
    auto it(begin(vec));
    if (it != end(vec))
        ss << *(it++);
    for (; it != end(vec); ++it)
        ss << " " << *it;
    return ss;
}

namespace foo {
    struct MyClass
    {
        std::vector<int> m_vec;
    };
    using ::operator<<;
    inline std::ostream& operator <<(std::ostream& ss, MyClass const& in)
    {
      return ss << "ClassVec: " << in.m_vec;
    }
}

int main() {
    foo::MyClass test;
    test.m_vec = {1,2,3};
    std::cout << test;
}

也就是说,有

using ::operator<<;
namespace foo

。原因是你的

std::ostream& operator <<(std::ostream& ss, MyClass const& in)
namespace foo内的

隐藏 ::operator<<。明确地using显式地,两个operator<<(全局和foo::)现在重载,因此两者都可用。

这样,您可以在operator<<中定义任意数量的foo::,并且全局版本仍可用。

答案 1 :(得分:0)

两种解决方案:

inline std::ostream& operator <<(std::ostream& ss, MyClass const& in)
{
  using ::operator<<;
  return ss << "ClassVec: " << in.m_vec;
}
inline std::ostream& operator <<(std::ostream& ss, MyClass const& in)
{ 
  ss << "ClassVec: ";
  ::operator<<(ss, in.m_vec);
  return ss;
}

有了这个,我的include_vector.h就变成了:

#pragma once

#ifdef _MSC_VER
#pragma warning( push )
#pragma warning (disable : 4996)
#endif

#include <vector>

typedef std::vector<double> DoubleVector;

template<class T>
inline std::ostream& operator <<(std::ostream& ss, std::vector<T> const& vec)
{
  auto it(begin(vec));
  if (it != end(vec))
    ss << *(it++);
  for (; it != end(vec); ++it)
    ss << " " << *it;
  return ss;
}

#ifdef _MSC_VER
#pragma warning( pop )
#endif