【问题标题】:Is there an equivalent for __if_exists in gnu c++?gnu c++ 中是否存在 __if_exists 的等价物?
【发布时间】:2010-09-23 14:31:39
【问题描述】:

__if_exists 是微软特定的关键字,用于在编译时测试标识符的存在性:

msdn:__if_exists

它可以非常方便地用于“伪造”模板特化,因为在某些情况下,它提供了一种比“真实”特化或重载等其他方法更简单、更易读且性能更好的方法。

但是现在我必须将一个大项目移植到 gnu c++,如果我不得不为我使用它的(诚然少数)场合找到其他方法,我想我会开始有点哭泣

【问题讨论】:

标签: c++ visual-c++ gcc


【解决方案1】:

在我看来,这是一个糟糕的关键字......

不幸的是,据我所知,它在 gcc 中不存在,但我可能根本不知道它。

处理这个问题的正确 C++ 方法是通过使用概念,即根据某些要求调整类型上执行的操作。

通常,它是用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 库的原因。

这个想法是检查将由一个概念对象执行,创建用于测试需求,因此您不必再专门化特征,这使开发更容易。但是我一直觉得 Boost.Concept 的文档有些欠缺。

【讨论】:

  • 嗯,你的替代方案对于我的目的来说也太复杂了,但如果几天后没有人提出真正简单的“是”,我会接受你的回答为“否”。
  • @MatthieuM。嗯,作为提出 __if_exists 的人,我确实在 20 年前介绍过它。这是我当时需要的一种原始形式的元编程 SFINAE,以便在 VC 6.0 编译器中实现 AOP。我承认与“未来”相比,它完全是蹩脚的:)
  • @user3291110:哇! 20 年前,我只知道 BASIC(它的两个版本)。带我回去……
  • @user3291110: 正是因为这种偶然的相遇,我才发现互联网是一个非凡的地方:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-19
  • 1970-01-01
  • 2013-06-21
  • 1970-01-01
  • 1970-01-01
  • 2012-12-17
  • 1970-01-01
相关资源
最近更新 更多