- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我试图了解模板和友元在 C++ 中是如何工作的。所以自己寻找/尝试一些例子。下面给出了一个我无法理解的示例:
版本 1
#include <iostream>
using namespace std;
//template<typename T> void func4();
//template<typename T> class NAME;
// template<typename T> std::ostream& operator<< (std::ostream&, NAME<T> const&);
template<typename T>
class NAME {
friend void func4<T>();
friend std::ostream& operator<< <T> (std::ostream&, NAME<T> const&);
};
int main()
{
cout << "Hello World" << endl;
return 0;
}
上面的版本1给出了以下错误:
prog.cc:13:17: error: variable or field 'func4' declared void
13 | friend void func4<T>();
| ^~~~~
prog.cc:13:17: error: expected ';' at end of member declaration
13 | friend void func4<T>();
| ^~~~~
| ;
prog.cc:13:22: error: expected unqualified-id before '<' token
13 | friend void func4<T>();
| ^
我的
第一个问题即使我已经评论了
func4
的前向声明和
operator<<
模板函数,那么我怎么能只得到
func4
的错误?这就是为什么
operator<<
没有错误的原因.
friend void func4<T>();
为了工作,我们需要注释掉声明
template<typename T> void func4();
同样对于
friend std::ostream& operator<< <T> (std::ostream&, NAME<T> const&);
为了工作,我们需要在程序开始时注释掉相应的前向声明。但是当我只注释掉
template<typename T> void func4();
语句,程序运行,并且
operator<<
没有错误.同样为什么我们没有收到
operator<<
的错误消息即使我没有注释掉相应的前向声明。
friend void func4<T>();
与...一样
friend void func4<>();
同样,是语句
friend std::ostream& operator<< <T> (std::ostream&, NAME<T> const&);
与...一样
friend std::ostream& operator<< <> (std::ostream&, NAME<T> const&);
我的想法是声明
friend void func4<>();
是使用语句
template <typename T> void func4();
声明的函数模板的特化。 .与此同时,当我们写
friend void func4<T>();
我们是
明确路过
T
所以在这种情况下,当我们写/打电话
func4<int>();
功能模板
func4<int>
将被初始化,然后占用内存。另一方面,专用模板函数已经占用了一些内存,因为我们必须在调用它之前提供它的定义。那么有人可以解释一下是否有
当我们使用 <T>
时是不同的当我们使用 <>
.总之,在我看来,在
<>
的情况下在
<T>
的情况下,将使用用户提供的特化当我们调用 func4() 时,将创建一个新的意图。所以有区别,因为在
<>
的情况下我们必须提供一个定义,它已经占用了一些空间(内存),而在
<T>
的情况下func4 只会在我们使用/调用它时占用空间(内存)。这是正确的结论吗?
There is no way to explicitly specify template arguments to overloaded operators, conversion functions, and constructors, because they are called without the use of the function name.
friend std::ostream& operator<< <T> (std::ostream&, NAME<T> const&);
因为它重载 operator << 。
最佳答案
答案 1 operator<<
没有错误因为你用过 using namespace std;
并在 std
命名空间已经重载 operator<<
.
答案 3
引用的语句谈论调用(即使用)重载运算符而不是定义/声明它们
答案 2
版本 1
#include <iostream>
template<typename T> void func4();
template<typename T>
class NAME {
//friend void func4<>();//this does not work because there is no way to deduce the template arguments
friend void func4<T>();//this works because here we have explicitly passed T as the template argument
};
int main()
{
std::cout << "Hello World" << std::endl;
NAME<int> n;
return 0;
}
在版本 1 中,我们有一个模板函数 func4<>。现在当你写
friend void func<T>();
和
friend void func<>();
,您正在成为类模板 NAME<> 的完全特化 friend 。原因
friend void func<>();
不起作用的原因是在这种情况下模板参数推导无法工作。而当你写
friend void func<T>();
你已经明确地传递了模板参数,所以这是有效的。这也意味着(
friend void func<T>
和
friend void func<>();
)本质上是模板函数 func<> 的相同特化。这将从我的下一个示例版本 2 中更加清楚。
#include <iostream>
template<typename T> class NAME;
template<typename T> std::ostream& operator<<(std::ostream&, const NAME<T>& );
template<typename T>
class NAME {
//both of the below friend declarations are equivalent
friend std::ostream& operator<< <T>(std::ostream&, const NAME<T>&);//this works
friend std::ostream& operator<< <>(std::ostream&, const NAME<T>&);//this works as well becasue of template argument deduction
};
int main()
{
std::cout << "Hello World" << std::endl;
NAME<int> n;
return 0;
}
在版本 2 中,我们有一个重载的运算符模板函数。两者
friend std::ostream& operator<< <T>(std::ostream&, const NAME<T>&);
和
friend std::ostream& operator<< <>(std::ostream&, const NAME<T>&);
是等效的并且是重载模板的相同特化
operator<< <T>
.它们之间的唯一区别是第二个使用模板参数推导。这是可能的,因为与版本 1 不同,我们有一个依赖于
T
的函数参数。这一次模板参数推导可以工作。在函数模板
func4<>
的情况下这是不可能的因为该函数不接受任何依赖于模板参数的参数。
关于c++ - C++ 中的类模板和友元,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69000196/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!