【问题标题】:Use implicit namespace on template arguments在模板参数上使用隐式命名空间
【发布时间】:2014-04-28 22:11:15
【问题描述】:

示例代码

namespace many {
    namespace namespaces {
        class Bar {
        };

        template<typename T>
        void foo() {
        }
    }
}

除了使用模板参数 Bar 调用 foo 之外没什么特别的了(如果没有 using 指令处于活动状态)来编写

many::namespaces::foo<many::namespaces::Bar>();

当我知道所有允许的类型都在命名空间many::namespaces 中时,这感觉有点傻。所以我的问题是,是否有某种方法可以在正确的命名空间中隐式查找 Bar?这样我就可以写了

many::namespaces::foo<Bar>();

这会非常方便,尤其是在我有多个模板参数要传递的情况下。我知道 ADL 会允许

foo<many::namespaces::Bar>();

但这对我来说有点奇怪。

那么有人知道是否存在针对此问题的无宏解决方案吗?

【问题讨论】:

  • 使用using 语句(using namespace &lt;namespace&gt;using = &lt;type&gt; 可以)。
  • 这个想法是不使用 using 指令。我想要一个 using 指令之类的东西,它只对函数调用有效。
  • 实际上,ADL 仅适用于采用该用户定义类型的参数的函数。它不允许你所说的调用语法。
  • AFAIK 我认为不使用宏或某种类型的别名就不可能做到这一点。
  • 啊,是的 - 写这篇文章时犯了一个错误。考虑创建一个作为非模板参数传递的“标签”类型,因此模板参数被推导出 => ADL 工作

标签: c++ templates namespaces metaprogramming template-meta-programming


【解决方案1】:

这样的解决方案不存在:

模板类型参数既不建立自己的范围,也不具有任何类似 ADL 的查找规则。此外,您不能向它传递任何任意令牌,但您需要向它传递一个类型。

因此,无论您传递什么,它都必须在您调用的周围范围内可找到。您可以对其进行限定,也可以通过 using / typedef 指令将其拉入周围的命名空间之一。

虽然 ADL 似乎是一个可行的替代方案(如果您添加一个参数),这意味着您手头有一些东西,其类型将导致 ADL 达到预期的结果。应该注意的是,在这种情况下,您只是在此范围内的其他地方编写了类型,您可以使用 decltype 重用它(可能还有一点 type_traits 魔法)。

P.S.:虽然宏可以达到预期的效果(通过建立一个额外的范围并在该特定范围内插入 using 命名空间指令,或者通过添加一个完整的限定),但您明确不想要一个。

【讨论】:

  • 我接受这个作为答案 - 如果有人真的有解决方案,我会改变它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-08
  • 2013-02-08
  • 2014-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多