使用 sfinae 测试命名空间成员是否存在

发布于 2024-09-16 16:32:57 字数 485 浏览 10 评论 0原文

我试图弄清楚是否可以使用 sfinae 来测试 命名空间 成员的存在。 谷歌对此保持沉默。我尝试过以下代码,但失败了。

namespace xyz{
 struct abc{};
}

struct abc{};

struct test_xyz{ 
 typedef char yes;
 typedef struct{ char a[2]; } no;

 template <class C> static yes test(xyz::C = xyz::C()); //lets assume it has default constructor
 template <class C> static no test(...);

 const bool has_abc = sizeof(test_xyz::test<abc>()) == sizeof(yes);
};

知道为什么吗?

问候,

I was trying to figure out if it is possible to use sfinae to test namespace member existence.
Google is rather silent about it. I've tried the following code, but it fails.

namespace xyz{
 struct abc{};
}

struct abc{};

struct test_xyz{ 
 typedef char yes;
 typedef struct{ char a[2]; } no;

 template <class C> static yes test(xyz::C = xyz::C()); //lets assume it has default constructor
 template <class C> static no test(...);

 const bool has_abc = sizeof(test_xyz::test<abc>()) == sizeof(yes);
};

Any idea why?

Regards,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

錯遇了你 2024-09-23 16:32:58

不,那行不通。也无法以这种方式使用 SFINAE(这是最后在 usenet 上讨论的针对某些 C++0x 组件的兼容性测试)。 xyz::C 中的 C 与模板参数完全无关。

请记住,模板不仅仅是宏。参数C不仅表示一段文本,而且表示一个语义实体。在本例中它是一种类型。它已经与它作为论证的含义绑定在一起了。也就是说,如果你的类有一个名为abc的成员,参数的含义仍然不会改变。

如果您想要的只是使用一些 struct xyz::abc(如果存在),而使用 other::abc,否则,您可以采取一些技巧来实现这一目标,但我'我不知道在不接触 xyz 的情况下执行此操作的方法

namespace others {
  struct abc{};
}

namespace fallbacks {
  using others::abc;
}

namespace xyz {
  using namespace fallbacks;
}

现在,如果您说 xyz::abc 且 xyz 包含如此声明的成员,那么它将引用该成员(该成员将隐藏 fallbacks 中的成员。但是,如果它不包含该成员,则将找到 using 指令的名称并引用 fallbacks::abc

No, that won't work. There is also no way to use SFINAE in such a way (this was last discussed on usenet for a compatibility test against some C++0x component). The C inside xyz::C is not related to the template parameter at all.

Remember that templates are not just macros. The parameter C denotes not just a piece of text, but a semantical entity. In this case it is a type. It's bound already to the meaning it has as an argument. That is, if your class had a member of name abc, the meaning of the parameter still would not change.

If all you want is to use some struct xyz::abc if it exists, and others::abc otherwise, you can do some tricks to get there, but I'm not aware of a way that does it without touching xyz

namespace others {
  struct abc{};
}

namespace fallbacks {
  using others::abc;
}

namespace xyz {
  using namespace fallbacks;
}

Now if you say xyz::abc and xyz contains a member declared so, it will refer to that member (that member will hide the one in fallbacks. However if it doesn't contain that member, then the using directive's name will be found and refer to fallbacks::abc.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文