gpt4 book ai didi

涵盖 const 和非 const 方法的 C++ 模板

转载 作者:IT老高 更新时间:2023-10-28 22:38:44 40 4
gpt4 key购买 nike

我遇到了 const 和非 const 版本的相同代码重复问题。我可以用一些代码来说明问题。这里有两个示例访问者,一个修改访问对象,一个不修改。

struct VisitorRead 
{
template <class T>
void operator()(T &t) { std::cin >> t; }
};

struct VisitorWrite
{
template <class T>
void operator()(const T &t) { std::cout << t << "\n"; }
};

现在这里是一个聚合对象——它只有两个数据成员,但我的实际代码要复杂得多:

struct Aggregate
{
int i;
double d;

template <class Visitor>
void operator()(Visitor &v)
{
v(i);
v(d);
}
template <class Visitor>
void operator()(Visitor &v) const
{
v(i);
v(d);
}
};

还有一个函数来演示以上内容:

static void test()
{
Aggregate a;
a(VisitorRead());
const Aggregate b(a);
b(VisitorWrite());
}

现在,这里的问题是 Aggregate::operator() 对于 const 和非 const 版本的重复。

是否有可能避免重复此代码?

我有一个解决方案是这样的:

template <class Visitor, class Struct>
void visit(Visitor &v, Struct &s)
{
v(s.i);
v(s.i);
}

static void test2()
{
Aggregate a;
visit(VisitorRead(), a);
const Aggregate b(a);
visit(VisitorWrite(), b);
}

这意味着不需要 Aggregate::operator() 并且没有重复。但是我对 visit() 是通用的,没有提到 Aggregate 类型这一事实感到不舒服。

有没有更好的办法?

最佳答案

我倾向于喜欢简单的解决方案,所以我会选择自由函数的方法,可能会添加 SFINAE 以禁用 Aggregate 以外的类型的函数:

template <typename Visitor, typename T>
typename std::enable_if< std::is_same<Aggregate,
typename std::remove_const<T>::type
>::value
>::type
visit( Visitor & v, T & s ) { // T can only be Aggregate or Aggregate const
v(s.i);
v(s.d);
}

如果您没有启用 C++0x 的编译器(或你可以从 boost type_traits 借用它们)

编辑:在编写 SFINAE 方法时,我意识到在 OP 中提供纯模板化(无 SFINAE)解决方案存在很多问题,其中包括如果您需要提供多个 visitable 类型,不同的模板会发生冲突(即它们会和其他模板一样好)。通过提供 SFINAE,您实际上只是为满足条件的类型提供 visit 函数,将奇怪的 SFINAE 转换为等价于:

// pseudocode, [] to mark *optional*
template <typename Visitor>
void visit( Visitor & v, Aggregate [const] & s ) {
v( s.i );
v( s.d );
}

关于涵盖 const 和非 const 方法的 C++ 模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7792052/

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