C++ 对模板参数使用隐式命名空间

C++ 对模板参数使用隐式命名空间,c++,templates,namespaces,metaprogramming,template-meta-programming,C++,Templates,Namespaces,Metaprogramming,Template Meta Programming,示例代码 namespace many { namespace namespaces { class Bar { }; template<typename T> void foo() { } } } 当我知道所有允许的类型都在名称空间many::namespaces中时,这感觉有点傻。所以我的问题是,是否有某种方法可以隐式地在正确的名称空间中查找Bar?那样我就能写作了 many::n

示例代码

namespace many {
    namespace namespaces {
        class Bar {
        };

        template<typename T>
        void foo() {
        }
    }
}
当我知道所有允许的类型都在名称空间
many::namespaces
中时,这感觉有点傻。所以我的问题是,是否有某种方法可以隐式地在正确的名称空间中查找Bar?那样我就能写作了

many::namespaces::foo<Bar>();
many::namespaces::foo();
这将非常方便,尤其是在需要传递多个模板参数的情况下。我知道ADL会允许的

foo<many::namespaces::Bar>();
foo();
但我觉得这有点奇怪


那么有人知道是否存在一个无宏的解决方案吗

这样的解决方案并不存在:

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

因此,无论您传递什么,都必须能够在调用的周围范围内找到它。您可以限定它,也可以通过
使用
/
typedef
指令将它拉入周围的一个名称空间

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


注意:虽然宏可以达到预期的结果(通过建立一个额外的作用域并在该特定的作用域中插入一个using namespace指令,或者通过预先设置一个完整的限定),但您显然不想要一个。

使用
using
语句(
using namespace
using=
就可以了)。其目的是不使用using指令。我想要一个像using指令这样的指令,它只对函数调用有效。实际上,ADL只对采用该用户定义类型的参数的函数有效。它不允许使用您提到的调用语法。AFAIK我认为不使用宏或某种类型的类型别名是不可能做到这一点的。啊,是的,写这篇文章时出错了。考虑创建一个“标记”类型,该类型作为非模板参数传递,因此模板参数得到推断=>ADL Works我接受这个作为答案-如果有人真的有解决方案,我会更改它
foo<many::namespaces::Bar>();