跳转至内容
  • A place to talk about whatever you want

    19 主题
    153 帖子
    SPeakS

    @johanvx 这个也是非常经典的公开课 中国大学Mooc和B站上应该都能找到视频

  • 7 主题
    20 帖子
    SPeakS

    @dustchens 链表结构损坏, 不闭环了 (如果问题解决可以把帖子状态设置为已解决

  • 开源软件 | 开源社区 | 开源理念 | 开源与商业 | 开源可持续发展 等相关话的交流讨论
    注: 这里的"开源"是泛化的共建共享概念, 范围包含 OSI的范围、自由软件、CC等相关内容

    57 主题
    242 帖子
    sunrisepeakS

    参考: http://forum.d2learn.org/post/493

  • 42 主题
    174 帖子
    abbkiritoA

    项目简单(仅为学习)
    我并不是很会这个框架 还在学习中
    环境准备(Ubuntu 22.04)

    gcc --version

    检查当前GCC版本:
    gcc --version
    e89ff7bd-b51b-4307-a36d-1633946d9aed-image.png
    ​​

    图1-1(C++版本查询)

    g++ -v --help 2>&1 | grep "std="

    若版本低于9.0,需执行以下升级操作:

    sudo apt update && sudo apt upgrade -y sudo apt install build-essential git cmake -y sudo apt install gcc-10 g++-10 -y

    验证C++17支持:

    g++ -v --help 2>&1 | grep "std="

    输出应包含gnu++17或c++17 例如:
    44588389-29ae-4f9f-b77a-a2b05a787e30-image.png

    3a1a02a9-8c7a-4c3f-a283-df44d21f8e0e-image.png

    MySQL依赖安装()

    安装MariaDB开发库drogon:

    sudo apt install -y libmariadb-dev

    创建源码目录并克隆仓库:

    mkdir drogon_src && cd drogon_src git clone https://github.com/drogonframework/drogon

    编译安装:

    cd drogon mkdir build && cd build cmake ..

    初次编译可能会遇到缺失trantor 子模块(Drogon 的网络库依赖)没有被正确下载或初始化。
    118d02d3-c6b4-48bf-b7aa-23320874463a-image.png

    笔者解决办法为:

    # 进入 Drogon 源码根目录 cd ~/drogon/drogon # 初始化并更新所有子模块 git submodule update --init --recursive

    编译

    编译安装 (nproc)调用当前可用核心数用于编译 make -j$(nproc)

    等待编译:
    3e65e501-04c1-4834-a887-5dceac785151-image.png
    环境验证
    验证drogon 是否安装成功 出现以下版本信息即可。
    dd1d52ba-a9af-4ac2-a3e2-3e7050a5d9fa-image.png

    *** 使用drogon_ctl创建项目。**
             
            在自己喜欢的文件夹中创建项目

    6369b916-ea68-47b6-8df7-b4b0ae4a5af7-image.png

    drogon_ctl create project Hello-drogon cd Hello-drogon

    进入Hello-drogon的controllers 中在终端新建一个控制器。

    #drogon_ctl create controller [参数] [控制器名(自定义)] drogon_ctl create controller -h drogonpic

    561bc505-8380-471c-b7cb-411941a64b8e-image.png
    编写测试接口
    23d96a12-94d0-4475-8af6-12fde87bad74-image.png
    编写一个简单的接口,该接口包含两个方法 路径为“api/pic”,“api/hello”,仅仅返回"hello drogon"的字符
    drogonpic.h 代码:

    // drogonpic.h 头文件编写。

    #pragma once #include <drogon/HttpController.h> using namespace drogon; class drogonpic : public drogon::HttpController<drogonpic> { public: METHOD_LIST_BEGIN // 确保类名正确 ADD_METHOD_TO(drogonpic::getPic, "/api/pic", Get); ADD_METHOD_TO(drogonpic::hello, "/api/hello", Get); METHOD_LIST_END //hello world void hello(const HttpRequestPtr& req, std::function<void(const HttpResponsePtr&)>&& callback) const; // 图片获取方法 void getPic(const HttpRequestPtr& req, std::function<void(const HttpResponsePtr&)>&& callback) const; };

    实现drogonpic.cc

    #include "drogonpic.h" #include <drogon/HttpResponse.h> #include <drogon/drogon.h> // 添加日志支持 #include <sys/stat.h> using namespace drogon; void drogonpic::getPic(const HttpRequestPtr& req, std::function<void(const HttpResponsePtr&)>&& callback) const { // 使用绝对路径更可靠 const std::string imagePath = "/home/xhm/xhm/Drogon-Project/Hello-drogon/assets/pic2.png"; // 记录路径信息(调试用) LOG_INFO << "Attempting to load image: " << imagePath; // 检查文件是否存在 struct stat buffer; if (stat(imagePath.c_str(), &buffer) != 0) { LOG_ERROR << "Image not found: " << imagePath; auto resp = HttpResponse::newHttpResponse(); resp->setStatusCode(k404NotFound); resp->setBody("Image not found"); callback(resp); return; } // 创建文件响应 auto resp = HttpResponse::newFileResponse(imagePath, "", CT_IMAGE_PNG); if (!resp) { LOG_ERROR << "Failed to open image: " << imagePath; resp = HttpResponse::newHttpResponse(); resp->setStatusCode(k500InternalServerError); resp->setBody("Failed to open image"); } else { LOG_INFO << "Image loaded successfully: " << imagePath; } callback(resp); } // 处理GET请求的方法 void drogonpic::hello(const HttpRequestPtr& req, std::function<void(const HttpResponsePtr&)>&& callback) const { // 创建HTTP响应对象 auto resp = HttpResponse::newHttpResponse(); // 设置响应内容 resp->setBody("hello world"); // 设置响应状态码(可选,默认200) // resp->setStatusCode(k200OK); // 通过回调返回响应 callback(resp); }

    对接口进行测试
    对api/hello 测试 使用apipost 进行测试 测试结果如下图所示:ip地址为linux主机的ip

    网页访问:
    04bb82cd-049f-4665-9037-9c5c44598877-image.png
    a8f35a9d-29d1-4a3c-ae98-4c4a87e71c1d-image.png

    压测结果:

    对api/pic 测试 给接口是返回一张图片
    dd3fe72b-3b64-4e04-8786-84498286286f-image.png

    网页访问:
    8ebacd02-fef5-4cfa-bbc5-61f575de4198-image.png
    压测结果:

    149852d2-c08d-466d-9d7e-c00547fa34ce-image.png
    总结

    : C++特性 代码示例 #pragma once #pragma once CRTP模板继承 class X : public drogon::HttpController<X> auto 自动推导 auto resp = HttpResponse::newHttpResponse(); 右值引用 && std::function<void(const T&)>&& callback std::function std::function<void(const HttpResponsePtr&)> 智能指针 HttpRequestPtr, HttpResponsePtr const 成员函数 void getPic(...) const C++调用C接口 stat(path.c_str(), &buffer)

  • 19 主题
    50 帖子
    SPeakS
    文章导读 一、类模板与模板特化(全特化与偏特化) 二、类模板与其模板特化的应用 三、模板特化存在性问题 一、类模板与模板特化(全特化与偏特化)

    从接受类型的角度
    类模板:全集R
    模板偏特化(部分特化):为全集的一个子集A
    模板全特化:为R中的一个"点",或者说为R中的一个元素
    匹配规则:越特化匹配优先级越高(见下面例子)

    98a9da6a-01af-4fc4-83ad-91b7ca549699-image.png

    1.类模板

    可以接受任意类型

    // R template<typename T> class A {}; // 类模板是能接受任意类型,A后面不需要(不能)任何处理 2.模板偏特化(局部特化)

    可以接受任意指针类型

    // A template<typename T> class A<T *> {}; // 类模板A的偏特化版本,在A后指出特化的范围 3.模板全特化

    指定接受int类型

    template<> class A<int> {} // 类模板A的全特化版本(已经是类模板的一个实例了),在A后直接指出明确类型int 4.例子: #include <iostream> #include <string> using namespace std; template<typename T> class A { public: A() { cout << "R" << endl; } }; /* 注释1 -- 接受指针 template<typename T> class A<T *> { public: A() { cout << "A" << endl; } }; */ /* 注释2 -- 接受int template<> class A<int> { public: A() { cout << "int" << endl; } }; */ int main() { A<string> r; // 1 A<char *> a; // 2 A<int> i; // 3 return 0; } 5.测试不同情况:

    当只有一个类模板(可接受任意类型R)存在时,1, 2, 3都使用类模板实例化

    v2-a53836d6d2a913d69c2fd90b0dd4371f_1440w.png

    注释1是接受所以指针类型(R的子集A),所以称其为类模板A的偏特化(范围特化)。即把类模版A所能接受的指针类型单独处理(实例化)。当取消注释1时:char * 将由这个模板类A的偏特化版本(范围特化,局部特化)处理。

    v2-2bd02b7f6a4dbb5cdbc586f98d76b92b_1440w.png

    注释2只接受int类型的参数(可以看出是全局R中的一个元素)。当你用int实例化A时,将会由这个全特化版本来实现(而不会使用可以接受任意类型的版本(泛化版))。

    v2-6a08120bfe6da8471d8fb374b2665a65_1440w.png

    二、类模板与其模板特化的应用 用模板的偏特化 实现一个 能移除任意类型const属性的模板类:remove_const 主要功能和用法: 功能: 给remove_const一个类型后 --1.(情况1)如果这个类型没有const属性则获得这个类型本身。 --2.(情况2)如果这个类型有const属性则移除它。 用法: remove_const<Type>::type 使用场景: 当拿到一个未知变量时,想获得这个变量(或对象)的非const的类型 1.实现情况1

    似乎没做什么事,aa是int符合情况1。但情况2不符合,bb没有变成int。

    #include <iostream> #include <type_traits> template<typename T> struct remove_const { using type = T; }; int main() { int a = 1; const int b = 2; remove_const<decltype(a)>::type aa = 3; remove_const<decltype(b)>::type bb = 4; std::cout << std::is_same<decltype(aa), int>::value << std::endl; std::cout << std::is_same<decltype(bb), int>::value << std::endl; return 0; }

    运行结果:
    v2-7a36de2df8473699ecc173f27351c876_1440w.png

    2.实现情况2

    从上面的实现可以看出,当传给模板的参数是带const类型时它还会返回带const属性的类型。同时从remove_const的定义也可以看出他是个 复读机 你给他什么类型他就给你什么类型。

    这时候可以使用上面介绍的偏特化的性质,来把带有带const的类型这个子集从全集中分离出来 特殊处理。如下:

    #include <iostream> #include <type_traits> template<typename T> struct remove_const { using type = T; }; template<typename T> struct remove_const<const T> { using type = T; }; int main() { int a = 1; const int b = 2; remove_const<decltype(a)>::type aa = 3; remove_const<decltype(b)>::type bb = 4; std::cout << std::is_same<decltype(aa), int>::value << std::endl; std::cout << std::is_same<decltype(bb), int>::value << std::endl; return 0; }

    运行结果:

    给带const的类型,写了一个特化版本。所以当remove_const接受一个带const的类型时,就会通过这个偏特化版本实例化,由于这个偏特化版本把const从类型中分离出来了,则这里的T就是没有const的类型,从而实现去除类型const的功能。

    v2-d337e4dc338fc9a90fcfa7ef9db27804_1440w.png

    三、模板特化存在性问题

    一个类模板的特化,是对某一个类模板的子集做特化处理的。而它不能"独立存在"。既只有存在一个类模板X, 才能存在对它特化的版本。

    template<typename T> class A<T *> {}; int main() { return 0; }

    v2-1023f2d6ec20e5efa6300629068527d6_1440w.png

  • 一个技术知识分享、学习、交流的社区

    15 主题
    46 帖子
    sunrisepeakS

    @johanvx 版块已创建, 可以检查确认一下是否有话题贴/Topic工具的权限

    https://forum.d2learn.org/category/21/blog-johan-xie
  • Got a question? Ask away!

    4 主题
    14 帖子
    SPeakS

    备注一下使数学公式的使用语法

    单行公式语法 - $ 你的公式 $

    $ log_2^n $

    $ log_2^n $

    多行公式语法 - $$ 你的公式 $$

    $$ log_2^n => log_2^9 = 3 , n = 9 $$

    $$
    log_2^n =>
    log_2^9 = 3, n = 9
    $$

公告栏 | Bulletin Board

欢迎加入d2learn社区 - 社区指南
Welcome to the d2learn Community - Community Guide

一个以 [知识、技术、代码、项目、想法、开源] 相关话题为主导的社区
A community focused on topics related to [knowledge, technology, code, projects, ideas, and open source].


在线用户