英文:
C2661 when using std::make_unique
问题
在尝试使用std::make_unique
时出现了错误。如果有人能指出我可能犯了一个非常简单的错误,我将不胜感激。我正在使用GLAD和GLFW作为第三方库。当我运行它时,我得到了一个错误代码C2661,错误消息是“'Window::Window':没有接受3个参数的重载函数”,出现在window.cpp中的以下代码片段:
return std::make_unique<Window>(std::move(nativeWindow), width, height);
Window.hpp
#pragma once
#include <memory>
#include <string>
#include <GLFW/glfw3.h>
struct Window final {
public:
std::unique_ptr<Window> createWindow(int width, int height, std::string title);
bool shouldClose() { return glfwWindowShouldClose(nativeWindow); }
void swapBuffers() { glfwSwapBuffers(nativeWindow); }
private:
GLFWwindow* nativeWindow;
int width;
int height;
std::string title;
};
Window.cpp
#include "Window.hpp"
std::unique_ptr<Window> Window::createWindow(int width, int height, std::string title) {
nativeWindow = glfwCreateWindow(width, height, title.c_str(), nullptr, nullptr);
glfwMakeContextCurrent(nativeWindow);
return std::make_unique<Window>(std::move(nativeWindow), width, height);
}
对于翻译,请注意:
-
std::make_unique
是C++中用于创建std::unique_ptr
对象的函数,它的参数是要包装的对象类型及其构造函数的参数。 -
错误代码C2661表明在调用
std::make_unique
时,找不到匹配的构造函数来接受给定的参数。可能是因为构造函数的签名不匹配或构造函数未正确定义。 -
代码中的
std::make_unique<Window>(std::move(nativeWindow), width, height)
尝试创建一个Window
对象的std::unique_ptr
,但是似乎Window
类没有一个接受这三个参数的构造函数。
希望这个信息对你有所帮助,以解决你的问题。
英文:
I have an error when I am trying to use std::make_unique. I probably have made a very simple mistake and I would be thankful if someone pointed it out. I am using GLAD and GLFW as 3rd party libraries. I get an error code of C2661 when I run it, C2661 'Window::Window': no overloaded function takes 3 arguments on the next code snippet in window.cpp.
return std::make_unique<Window>(std::move(nativeWindow), width, height);
Window.hpp
#pragma once
#include <memory>
#include <string>
#include <GLFW/glfw3.h>
struct Window final {
public:
std::unique_ptr<Window> createWindow(int width, int height, std::string title);
bool shouldClose() { return glfwWindowShouldClose(nativeWindow); }
void swapBuffers() { glfwSwapBuffers(nativeWindow); }
private:
GLFWwindow* nativeWindow;
int width;
int height;
std::string title;
};
Window.cpp
#include "Window.hpp"
std::unique_ptr<Window> Window::createWindow(int width, int height, std::string title) {
nativeWindow = glfwCreateWindow(width, height, title.c_str(), nullptr, nullptr);
glfwMakeContextCurrent(nativeWindow);
return std::make_unique<Window>(std::move(nativeWindow), width, height);
}
sorry for bad code quality.
答案1
得分: 6
Your Window
class does not have a constructor taking GLFWwindow*, int, int
as would be required for this:
return std::make_unique<Window>(std::move(nativeWindow), width, height);
However, it seems you are encapsulating the wrong thing.
- If a
Window
instance is copied or moved, there will suddenly be two owners of theGLFWwindow
, with a doublefree
later likely. - When a
Window
is destroyed, you don't callglfwDestroyWindow
to free the resource, which will leak.
Read The rule of 3/5/0.
What you should be doing is really to store a unique_ptr<GLFWwindow>
in Window
to make the problems mentioned above go away without having to implement the manual resource management mentioned in The rule of 3/5/0.
Example:
struct Window final {
public:
Window(int width, int height, std::string title);
inline bool shouldClose() { return glfwWindowShouldClose(nativeWindow.get()); }
inline void swapBuffers() { glfwSwapBuffers(nativeWindow.get()); }
private:
struct glfwWindowDestroyer {
void operator()(GLFWwindow* win) const {
glfwDestroyWindow(win);
}
};
std::unique_ptr<GLFWwindow, glfwWindowDestroyer> nativeWindow;
int width;
int height;
std::string title;
};
The constructor implementation would then be:
Window::Window(int width, int height, std::string title) :
nativeWindow(glfwCreateWindow(width, height, title.c_str(), nullptr, nullptr)),
width(width),
height(height),
title(std::move(title))
{
glfwMakeContextCurrent(nativeWindow.get());
}
That way the createWindow
function (which should have been static
) can be removed. Just create Window
s like normal C++ objects. Window
objects are now safely moveable (and non-copyable) without any extra tinkering.
If you for some reason still would like to have a helper function to create unique_ptr<Window>
s, you can, but as you will see, it will be rather pointless:
std::unique_ptr<Window>
Window::createWindow(int width, int height, std::string title) {
return std::make_unique<Window>(width, height, title);
}
There's not much of a gain to call Window::createWindow
instead of just calling std::make_unique<Window>
directly. Also, the use of unique_ptr<Window>
s is dubious. Window
is final
and it's not inheriting from anything. You should probably just store Window
s directly in a container.
英文:
Your Window
class does not have a constructor taking GLFWwindow*, int, int
as would be required for this:
return std::make_unique<Window>(std::move(nativeWindow), width, height);
However, it seems you are encapsulating the wrong thing.
- If a
Window
instance is copied or moved, there will suddenly be two owners of theGLFWwindow
, with a doublefree
later likely. - When a
Window
is destroyed, you don't callglfwDestroyWindow
to free the resource, which will leak.
Read The rule of 3/5/0.
What you should be doing is really to store a unique_ptr<GLFWwindow>
in Window
to make the problems mentioned above go away without having to implement the manual resource management mentioned in The rule of 3/5/0.
Example:
struct Window final {
public:
Window(int width, int height, std::string title);
inline bool shouldClose() { return glfwWindowShouldClose(nativeWindow.get()); }
inline void swapBuffers() { glfwSwapBuffers(nativeWindow.get()); }
private:
struct glfwWindowDestroyer {
void operator()(GLFWwindow* win) const {
glfwDestroyWindow(win);
}
};
std::unique_ptr<GLFWwindow, glfwWindowDestroyer> nativeWindow;
int width;
int height;
std::string title;
};
The constructor implementation would then be:
Window::Window(int width, int height, std::string title) :
nativeWindow(glfwCreateWindow(width, height, title.c_str(), nullptr, nullptr)),
width(width),
height(height),
title(std::move(title))
{
glfwMakeContextCurrent(nativeWindow.get());
}
That way the createWindow
function (which should have been static
) can be removed. Just create Window
s like normal C++ objects. Window
objects are now safely moveable (and non-copyable) without any extra tinkering.
If you for some reason still would like to have a helper function to create unique_ptr<Window>
s, you can, but as you will see, it will be rather pointless:
std::unique_ptr<Window>
Window::createWindow(int width, int height, std::string title) {
return std::make_unique<Window>(width, height, title);
}
There's not much of a gain to call Window::createWindow
instead of just calling std::make_unique<Window>
directly. Also, the use of unique_ptr<Window>
s is dubious. Window
is final
and it's not inheriting from anything. You should probably just store Window
s directly in a container.
答案2
得分: 0
这行:
```c++
std::make_unique<Window>(std::move(nativeWindow), width, height);
假设你的 Window 类型有以下可用的构造函数:
Window::Window(GLFWwindow* win, int width, int height)
可以通过添加正确的构造函数来解决这个问题(我还传递了标题,你没有存储它)。
Window.hpp
#pragma once
#include <memory>
#include <string>
#include <GLFW/glfw3.h>
struct Window final {
public:
// Window 对象的构造函数
Window(GLFWwindow* win, int w, int h, std::string title)
: nativeWindow(win), width(w), height(h), title(title)
{
}
// 我假设你希望这个方法是静态的?
// 作为成员函数几乎没有多大意义。
static
std::unique_ptr<Window> createWindow(int width, int height, std::string title);
bool shouldClose() { return glfwWindowShouldClose(nativeWindow); }
void swapBuffers() { glfwSwapBuffers(nativeWindow); }
private:
GLFWwindow* nativeWindow;
int width;
int height;
std::string title;
};
#include "Window.hpp"
std::unique_ptr<Window> Window::createWindow(int width, int height, std::string title) {
nativeWindow = glfwCreateWindow(width, height, title.c_str(), nullptr, nullptr);
glfwMakeContextCurrent(nativeWindow);
return std::make_unique<Window>(nativeWindow, width, height, title);
}
然后,你应该这样调用这个方法:
std::unique_ptr<Window> ptr = Window::createWindow(640, 480, "hello")
<details>
<summary>英文:</summary>
This line:
```c++
std::make_unique<Window>(std::move(nativeWindow), width, height);
assumes your Window type has the following constructor available:
Window::Window(GLFWwindow* win, int width, int height)
This can be fixed by adding the correct constructor (I've also passed through the title, which you weren't storing anywhere).
Window.hpp
#pragma once
#include <memory>
#include <string>
#include <GLFW/glfw3.h>
struct Window final {
public:
// constructor for Window object
Window(GLFWwindow* win, int w, int h, std::string title)
: nativeWindow(win), width(w), height(h), title(title)
{
}
// I assume you meant for this method to be static?
// It makes very little (if any sense) as a member function.
static
std::unique_ptr<Window> createWindow(int width, int height, std::string title);
bool shouldClose() { return glfwWindowShouldClose(nativeWindow); }
void swapBuffers() { glfwSwapBuffers(nativeWindow); }
private:
GLFWwindow* nativeWindow;
int width;
int height;
std::string title;
};
#include "Window.hpp"
std::unique_ptr<Window> Window::createWindow(int width, int height, std::string title) {
nativeWindow = glfwCreateWindow(width, height, title.c_str(), nullptr, nullptr);
glfwMakeContextCurrent(nativeWindow);
return std::make_unique<Window>(nativeWindow, width, height, title);
}
Then you should be call the method like so:
std::unique_ptr<Window> ptr = Window::createWindow(640, 480, "hello")
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论