好友、模板、命名空间
friend, template, namespace
我想要一个模板化的友元函数。但是,我不知道如何使其在没有模板化功能的情况下以相同的方式工作。 下面是一个示例代码
#include <iostream>
namespace ns{
struct Obj {
friend void foo(Obj){std::cout << "no problem" << std::endl;}
template<typename T>
friend void bar(Obj){std::cout << "problem" << std::endl;}
};
}
int main() {
ns::Obj obj;
foo(obj); // Compile
bar<int>(obj); // Not compile
return 0;
}
> 在 C++20 之前,您需要告诉编译器bar
是模板的名称,以便它知道<
启动模板参数列表并且不是小于运算符:
template<char> void bar() = delete;
int main() {
ns::Obj obj;
foo(obj); // Compile
bar<int>(obj); // Now compiles too
return 0;
}
请注意,重载bar
要做的就是成为函数模板。签名无关紧要,只要它不是好到干扰重载分辨率;()
是一个不错的选择,因为根据定义,我们至少传递一个参数,因此不带参数的函数模板永远不可行。
或者,您可以重新设计bar
以从标记参数推断T
:
template<class T>
struct type {};
namespace ns{
struct Obj {
// ...
template<typename T>
friend void bar(Obj, type<T>) { /* ... */ }
};
}
// ...
bar(obj, type<int>()); // OK
在 C++20 中,编译器将假定bar
在看到模板时命名模板<
并且名称查找未找到任何内容,因此您的代码将正常工作。
直接的方法是添加一个前向声明,并让使用限定查找来定位函数:
namespace ns{
struct Obj;
void foo(Obj);
template<typename T>
void bar(Obj);
struct Obj {
friend void foo(Obj){std::cout << "no problem" << std::endl;}
template<typename T>
friend void bar(Obj){std::cout << "problem " << std::endl;}
};
} // namespace ns
int main() {
ns::Obj obj;
ns::foo(obj); // Ok
ns::bar<int>(obj); // Ok
return 0;
}
相关文章:
- 如何使 std::sort 在 std::swap 和我的命名空间的模板化交换之间没有名称冲突?
- 将好友从模板导出到全局命名空间
- Boost.Python :C++模板类型匹配的嵌套命名空间
- 使用类指针重载C++命名空间函数模板专用化替代方法?
- 模板实现文件中的匿名命名空间
- 用于替换回调命名空间的模板?
- 有关命名空间和模板参数的名称的问题
- C++ 使用命名空间时,模板函数无法使用 g++ 进行编译
- 好友、模板、命名空间
- 在 c++ 中定义命名空间中模板类的友元函数时出现问题
- C++ ,错误:命名空间'std'中的'shared_ptr'未命名模板类型
- 在模板参数的函数中使用一个命名空间或另一个命名空间
- 命名空间和类中的可变参数模板函数
- 命名空间'std'中的'vector'没有模板类型
- 如何在另一个名称空间内从另一个命名空间内明确专业化功能模板
- 使用显式命名空间限定符时模板实例化行为是否发生变化?
- BGL:不同命名空间中模板的专用化
- 匿名命名空间中模板化类的友元
- 为什么这个重载/命名空间/模板相关的C++代码不编译?
- 叮当虫?命名空间模板类的友元