__ if_exists是一个特定于Microsoft的关键字,用于在编译时测试标识符的存在:
它可以非常方便地使用“伪造”模板专业化,因为在某些情况下它提供了比其他方法(如“真正的”专业化或重载或其他方法)更加简单,可读和更好的表现方式。
但是现在我必须将一个大项目移植到gnu c ++,我想我会开始有点哭,如果我必须找到其他方法(我认为很少)我使用它
答案 0 :(得分:5)
在我看来,这是一个蹩脚的关键词...
不幸的是,就我所知,它在gcc中并不存在,但我可能根本就不知道它。
正确的C ++处理方法是通过使用Concepts,即根据某些要求调整类型上的操作。
通常情况下,它是使用traits
而非真实概念执行的,因为它更容易实现:
template <typename T>
struct has_dump: boost::mpl::false_ {};
然后通过专门化has_dump
结构来转储启用您的类型。
最简单的方法是定义3个方法,一个用于路由,另外两个用于执行不同的分支:
template <typename T>
void dump(T& t, boost::mpl::true_ const& dummy)
{
t.Dump();
}
template <typename T>
void dump(T& t, boost::mpl::false_ const& dummy)
{
std::cout << typeid(T).name() << " does not have Dump\n";
}
template <typename T>
void dump(T& t) { dump(t, has_dump<T>()); }
类型特征的另一个用途是与enable_if
设施结合使用:
template <typename T>
typename boost::enable_if< has_dump<T> >::type dump(T& t)
{
t.Dump();
}
// disable_if exists too...
此处,如果类型没有启用has_dump
,则可以获得编译时错误,而不是运行时错误消息,不确定是否需要。
然而,这两种方法都非常麻烦,因为检测不是自动化的。这就是为什么有Boost.Concept库。
我们的想法是,检查将由一个Concept对象执行,该对象是为了测试需求而创建的,因此您不必再专门化特征,这使得开发更容易。但是我总是发现Boost.Concept的文档有点缺乏。