有一个模板:
template <typename T, template <typename ELEM, typename ALLOC=std::allocator<ELEM> > class Cont=std::vector>
class VehiclesContainer {
public:
VehiclesContainer(std::initializer_list<T> l):container(l){};
virtual ~VehiclesContainer(){};
virtual void addVehicle(T elem);
virtual T getFirst() const;
template
<typename U, template <typename ELEM2, typename ALLOC=std::allocator<ELEM2> > class Cont2>
friend std::ostream& operator<<(std::ostream& out, const VehiclesContainer<U,Cont2>& obj);
private:
Cont<T> container;
};
我有运算符<<作为友元类:
template
<typename T,template <typename ELEM,typename ALOC=std::allocator<ELEM> > class Cont>
std::ostream& operator<<(std::ostream& out,const VehiclesContainer<T,Cont>& obj){
typename Cont<T>::const_iterator it;
for(it=obj.container.begin(); it!=obj.container.end(); ++it)
out << *it << " ";
return out;
}
我想做的是为整数函数专门化,其中输出的元素之间将有一个 -
而不是空格。我试过了
template
<int,template <typename ELEM,typename ALOC=std::allocator<ELEM> > class Cont>
std::ostream& operator<<(std::ostream& out,const VehiclesContainer<int,Cont>& obj){
typename Cont<int>::const_iterator it;
for(it=obj.container.begin(); it!=obj.container.end(); ++it)
out << *it << "-";
return out;
}
但是当我编译的时候主要有
VehiclesContainer<int,std::vector > aStack1({10,20,30});
std::cout << aStack1;
运算符<<的一般形式被调用而不是我的特化。我想我并没有真正专注于它。对如何声明 friend 类的特化有帮助吗?
根据WhozCraig的回答解决
前向声明:
template <typename T, template <typename ELEM, typename ALLOC=std::allocator<ELEM> > class Cont=std::vector>
class VehiclesContainer;
template <typename T, template <typename ELEM, typename ALLOC=std::allocator<ELEM> > class Cont>
std::ostream& operator<< (std::ostream& out, const VehiclesContainer<T,Cont>& obj);
template <template <typename ELEM, typename ALLOC=std::allocator<ELEM> > class Cont>
std::ostream& operator<< (std::ostream& out, const VehiclesContainer<int,Cont>& obj);
类内声明:
friend std::ostream& operator << <T,Cont>(std::ostream&,
const VehiclesContainer<T,Cont>&);
friend std::ostream& operator << <Cont>(std::ostream&,
const VehiclesContainer<int,Cont>&);
友元函数的定义:
template <typename T, template <typename ELEM, typename ALLOC=std::allocator<ELEM> > class Cont>
std::ostream& operator <<(std::ostream& os, const VehiclesContainer<T,Cont>& obj)
{
if (obj.container.size() > 0)
{
os << obj.container.front();
for (auto it = std::next(obj.container.begin()); it != obj.container.end(); ++it)
os << ' ' << *it;
}
return os;
}
template <template <typename ELEM, typename ALLOC=std::allocator<ELEM> > class Cont>
std::ostream& operator << (std::ostream& os, const VehiclesContainer<int,Cont>& obj)
{
if (obj.container.size() > 0)
{
os << obj.container.front();
for (auto it = std::next(obj.container.begin()); it != obj.container.end(); ++it)
os << '-' << *it;
}
return os;
}
最佳答案
这是一种做你想做的事情的方法。我随意在模板参数中使用可变参数来节省我自己的一些输入,但最终前提应该是显而易见的:
#include <iostream>
#include <vector>
#include <cstdlib>
// forward declaration of template class
template <class T, template<class, class...> class Cont = std::vector, class... Args>
class VehiclesContainer;
// generic template for all T and all container types
template<class T, template<class, class...> class Cont = std::vector, class... Args>
std::ostream& operator <<(std::ostream&, const VehiclesContainer<T,Cont,Args...>&);
// specific template for only int and all container types
template<template<class, class...> class Cont = std::vector, class... Args>
std::ostream& operator << (std::ostream& os, const VehiclesContainer<int,Cont,Args...>& obj);
template <class T, template<class, class...> class Cont, class... Args>
class VehiclesContainer
{
public:
VehiclesContainer(std::initializer_list<T> l)
: container(l)
{};
// friend overloaded to `int` type
friend std::ostream& operator << <T,Cont,Args...>(std::ostream&,
const VehiclesContainer<T,Cont,Args...>&);
friend std::ostream& operator << <Cont, Args...>(std::ostream&,
const VehiclesContainer<int,Cont,Args...>&);
private:
Cont<T,Args...> container;
};
template<class T, template<class, class...> class Cont, class... Args>
std::ostream& operator <<(std::ostream& os, const VehiclesContainer<T,Cont,Args...>& obj)
{
if (obj.container.size() > 0)
{
os << obj.container.front();
for (auto it = std::next(obj.container.begin()); it != obj.container.end(); ++it)
os << ' ' << *it;
}
return os;
}
template<template<class, class...> class Cont, class... Args>
std::ostream& operator << (std::ostream& os, const VehiclesContainer<int,Cont,Args...>& obj)
{
if (obj.container.size() > 0)
{
os << obj.container.front();
for (auto it = std::next(obj.container.begin()); it != obj.container.end(); ++it)
os << '-' << *it;
}
return os;
}
int main()
{
VehiclesContainer<std::string> vcString { "Camero", "Corvette" };
VehiclesContainer<int> vcInt { 1,2,3 };
std::cout << vcString << '\n';
std::cout << vcInt << '\n';
return 0;
}
输出
Camero Corvette
1-2-3
关于c++ - 如何声明模板友元函数的特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21793854/