我有一个名称空间my_space
并将函数模板定义为
namespace my_space
{
template<class T>
ostream operator<<(ostream& os, T const& t)
{ ... }
}
我希望此功能仅适用于my_space
中的我的课程,或者对于my_space
以外的某些类型可能会有歧义。例如
namespace my_space
{
void f()
{
cout << "test"; //overload ambiguous
}
}
有什么方法可以避免这种情况吗?
答案 0 :(得分:2)
我们可以通过一些ADL(依赖于参数的查找)和辅助函数来完成这个。
在这种情况下,我们使用namespace_test_helper
,当且仅当查询的类型(或其依赖类型)来自true_type
时,才会返回my_namespace
。
namespace support {
template<class...Ts>
constexpr std::false_type namespace_test_helper( Ts&&... ) { return {}; }
template<class T>
constexpr auto namespace_test( T&& t ) {
return namespace_test_helper( std::forward<T>(t));
}
}
namespace my_namespace {
template<class T>
constexpr std::true_type namespace_test_helper( T&& ) { return {}; }
template<class T,
class=std::enable_if_t<decltype(::support::namespace_test( std::declval<T>() )){}>
>
std::ostream& operator<<( std::ostream& os, T const& t ) {
return os << "my <<";
}
enum bob {};
void test() {
std::cout << "hello world\n";
std::cout << bob{} << "\n";
}
}
int main() {
::my_namespace::test();
std::cout << ::my_namespace::bob{} << "\n";
}
请注意,my_namespace
内的模板参数类型也可以找到它。
我们可以将其扩展到检测哪些命名空间来自哪些;但是你必须为每个这样的命名空间定义一个不同的类型。 std::integral_constant<std::size_t, I>
可以使用,但您负责为每个命名空间设置唯一的I
。