gpt4 book ai didi

c++ - 使用模板类的嵌套类型作为模板参数

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:28:56 25 4
gpt4 key购买 nike

我想使用模板类的嵌套类型实现模板函数。

我刚读过here最好实现 operator <<作为非成员和非友元函数。因此我决定移动函数 toStream()tableToStream()外面MyClass :

template <typename T>
class MyClass
{
public:
typedef boost::dynamic_bitset<> BoolTable;
typedef std::vector<T> MsgTable;
private:
BoolTable b_;
MsgTable m_;
public:
const BoolTable& getB() const { return b_; }
const MsgTable & getM() const { return m_; }

std::ostream& toStream (std::ostream& os) const
{
os <<"Bool: "; tableToStream (os, getB()); os <<'\n';
os <<"Msg:"; tableToStream (os, getM()); os <<'\n';
return os;
}

template <typename TABLE>
std::ostream& tableToStream (std::ostream& os, const TABLE& table) const
{
for (int i=0; i < table.size(); ++i)
os << table[i] <<',';
return os;
}
};

template <typename T>
std::ostream& operator << (std::ostream& os, const MyClass<T> mc)
{
return mc.toStream(os);
}

很容易转换MyClass::toStream()进入 operator <<非成员和非友元函数:

template <typename T>
std::ostream& operator << (std::ostream& os, const MyClass<T>& mc)
{
os <<"Bool: "; mc.tableToStream (os, mc.getB()); os <<'\n';
os <<"Msg:"; mc.tableToStream (os, mc.getM()); os <<'\n';
return os;
}

但我只想使用 operator <<而不是调用 MyClass::tableToStream() :

template <typename T>
std::ostream& operator << (std::ostream& os, const MyClass<T>& mc)
{
os <<"Bool: "<< mc.getB() <<'\n';
os <<"Msg:" << mc.getM() <<'\n';
return os;
}

对于函数 MyClass::tableToStream()我可以使用以下实现,但这可能会弄乱流输出,因为函数太通用(任何类型都可以是 TABLE )。

template <typename TABLE>
std::ostream& operator << (std::ostream& os, const TABLE& table)
{
for (int i=0; i < table.size(); ++i)
os << table[i] <<',';
return os;
}

因此,我想限制为 MyClass嵌套类型 .以下是我转换 MyClass::tableToStream() 的尝试之一成标准operator <<非成员和非友元函数:

template <typename T, typename MyClass<T>::TABLE>
std::ostream& operator << (std::ostream& os, const TABLE& table)
{
for (int i=0; i < table.size(); ++i)
os << table[i] <<',';
return os;
}

但错误是关于typename MyClass<T>::TABLE .

最佳答案

既然你已经澄清了你的问题很多,我的第一个答案不再适用,我会删除编辑它给你一些可能更适合你的东西:

更新的答案:您希望限制模板只接受在 MyClass 模板中定义的类型。这些约束通常通过应用 SFINAE 来实现,尤其是通过 std::enable_if (或 boost::enable_if ,如果您的库缺少对 C++11 的那部分支持)。可悲的是,没有像 is_typedeffed_inside 这样的特征。可以用于您的情况。更糟糕的是:没有办法仅使用普通的 typedef 来编写这样的特征,因为在给定的类中进行 typedeff 没有什么特别的——编译器无法确定(并且不感兴趣)是否给定的已知类型在某处有一些别名。

但是如果您的 typedef 正是您在问题中显示的那些,我有好消息要告诉您:您正好需要两个 operator<<为此:

  1. 一个 boost::dynamic_bitset<> ,因为这是用于任何 MyClass 实例化的 BoolTable。
  2. 另一个,模板化,用于std::vector<T> , 因为那是每个对应 MyClass<T> 的 MsgTable .

缺点是,使用这个模板化的 operator<< ,您将能够输出任何 std::vector<FooBar> , 即使FooBar与 MyClass 的任何使用完全无关。但这适用于适当 operator<< 的任何其他可能实现。的 - 如果对 MSG 参数没有明确的限制,则对 FooBar 制作 std::vector<FooBar> 没有限制一个可行的MyClass<MSG>::MsgTable .

我对你的问题的结论:你想要 operator<<因为它的外观很方便,因为它通常用于此目的。在您的情况下,您可以为 MyClass<MSG> 提供它对象,但无法单独针对内部 typedef 执行此操作。

我会这样实现:

template <class MSG>
class MyClass {
/* ... */
public:
// instead of declaring op<< a friend, redirect to a method that has
// natural access to private members
std::ostream& printToStream(std::ostream& os) const
{
os << "Bool: ";
tableToStream (getB(), os);
os <<"\nMsg:";
tableToStream (getM(), os);
return os <<'\n';
}
private:
// make this one private so nobody can misuse it to print unrelated stuff
template <class Table>
static void tableToStream(Table const& table, std::ostream& os)
{
std::copy(begin(table), end(table), ostream_iterator(os, ", "));
}
};

template <typename MSG>
std::ostream& operator << (std::ostream& os, const MyClass<MSG>& mc)
{
return mc.printToStream(os);
}

关于c++ - 使用模板类的嵌套类型作为模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14982643/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com