C++智能指针报错模板无法实列化对象

img


用了指针指针包装第三方库Book对象 Book对象的本质是一个模板类


#include <iostream>
#include <libxl.h>
#include <cstdlib>
#include <memory>
#include <string>

#pragma comment(lib,"libxl.lib")

const std::string filepath = "H:\\szubooktest.xlsx";

int main()
{
    std::shared_ptr<libxl::Book> szu_book = std::make_shared<libxl::Book>(xlCreateXMLBookA());

    if (szu_book->load(filepath.data())) std::cout << "文档打开成功!" << std::endl;
    else
    {
        std::cout << "文档打开失败!" << std::endl;
        system("pause");
        return 0;
    }

    system("pause");
    return 0;
}

如果不写智能指针就没问题

#include <iostream>
#include <libxl.h>
#include <cstdlib>
#include <memory>
#include <string>

#pragma comment(lib,"libxl.lib")

const std::string filepath = "H:\\szubooktest.xlsx";

int main()
{
    //std::shared_ptr<libxl::Book> szu_book = std::make_shared<libxl::Book>(xlCreateXMLBook());
    libxl::Book* szu_book = xlCreateBook();

    if (szu_book->load(filepath.data())) std::cout << "文档打开成功!" << std::endl;
    else
    {
        std::cout << "文档打开失败!" << std::endl;
        system("pause");
        return 0;
    }

    system("pause");
    return 0;
}

模板的模板 对于 make_shared 有点复杂 需要用到 initializer_list
你可以看看这个
http://t.csdn.cn/FXcyr

直接试试

std::shared_ptr<libxl::Book> szu_book(xlCreateXMLBook());

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/7455559
  • 这篇博客你也可以参考下:1.c++算法打卡,定义一个Book(图书)类。
  • 除此之外, 这篇博客: 轻项目练习——图书管理代码中的 创建 Book 类 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    创建 book 包,然后创建 Book 类。包括:名字、作者、价格、种类、是否被借出。在类里面写好构造方法,重写 String 方法:

    public class Book {
        private String name;
        private String author;
        private int price;
        private String type;
        private boolean isBorrowed;
        public Book(String name, String author, int price, String type) {
            this.name = name;
            this.author = author;
            this.price = price;
            this.type = type;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getAuthor() {
            return author;
        }
        public void setAuthor(String author) {
            this.author = author;
        }
    
        public int getPrice() {
            return price;
        }
        public void setPrice(int price) {
            this.price = price;
        }
        public String getType() {
            return type;
        }
        public void setType(String type) {
            this.type = type;
        }
        public boolean isBorrowed() {
            return isBorrowed;
        }
        public void setBorrowed(boolean borrowed) {
            isBorrowed = borrowed;
        }
        @Override
        public String toString() {
            return "Book{" +
                    "name='" + name + '\'' +
                    ", author='" + author + '\'' +
                    ", price=" + price +
                    ", type='" + type + '\'' +
                    ((isBorrowed == true)?" 已借出 ":" 未借出 ") +
                    '}';
        }
    }
    
  • 以下回答来自chatgpt:

    在C++中使用智能指针时,会出现模板无法实例化的错误,可能的原因是第三方库中的Book对象是一个模板类,并不是一个具体的类型。智能指针在使用时需要知道指针所指向的对象的具体类型,以便正确地管理内存。然而,由于模板类在编译时并不会生成实际的类定义,而是在使用时根据模板参数生成对应的类定义,所以在编译阶段无法确定智能指针所指向的具体类型,从而导致模板无法实例化的错误。

    解决这个问题的方法有两种:

    1. 使用具体类型代替模板参数: 如果你能够确定Book类在实际使用中的具体类型,那么可以将智能指针指向该具体类型而不是模板类,这样就可以避免模板无法实例化的错误。例如,如果Book类具体实现为Book,则可以使用unique_ptr>或shared_ptr>来管理Book对象的内存。

    ```cpp #include #include "ThirdPartyLibrary.h" // 包含第三方库的头文件 using namespace std;

    // 使用unique_ptr指向具体类型Book unique_ptr> bookPtr(new Book(args));

    // 或者使用shared_ptr shared_ptr> bookPtr = make_shared>(args); ```

    1. 使用类型擦除技术: 如果无法确定Book类的具体类型,或者需要在运行时才能确定类型,可以使用类型擦除技术,例如使用void指针或模板类包装器来管理Book对象的内存。可以使用void指针来包装Book对象的指针,然后将其传递给智能指针进行管理。在使用时,需要将void指针转换回原始类型才能进行操作。

    ```cpp #include #include "ThirdPartyLibrary.h" // 包含第三方库的头文件 using namespace std;

    void* bookRawPtr = new Book(args); // 创建void指针来指向Book对象的指针

    // 使用智能指针进行管理时,需要将void指针转换为原始类型 unique_ptr> bookPtr(reinterpret_cast*>(bookRawPtr));

    // 使用智能指针进行操作时,需要将智能指针转换为void指针后再传递给第三方库 ThirdPartyLibraryFunction(reinterpret_cast(bookPtr.get())); ```

    需要注意的是,在使用智能指针管理Book对象的内存时,如果第三方库需要原始指针,需要将智能指针转换为原始指针后再传递给第三方库。在析构智能指针时,会自动释放所管理的内存,无需手动删除。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^