You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于SFINAE与std::enable_if的C++类型包装类实现练习

完善基于std::enable_if的type_wrap结构体实现

看起来你想用SFINAE机制通过std::enable_if实现一个能包装特定类型的type_wrap结构体,还想通过构造函数重载区分不同类型的处理逻辑对吧?我来帮你把这段代码补全,让它能正确完成类型包装和信息输出的功能。

先给你看完整的可运行代码:

#include <type_traits>
#include <typeinfo>
#include <iostream>
#include <string>

using std::enable_if;
using std::is_same;
using std::cout;
using std::endl;
using std::string;

template<typename T>
struct type_wrap {
    // 存储被包装的实例
    T value;

    // 专门处理int类型的构造函数,通过SFINAE启用
    type_wrap(typename enable_if<is_same<int, T>::value, T>::type&& rrT)
        : value(std::move(rrT)) {
        cout << "The wrapped type is int, value: " << value << endl;
    }

    // 扩展:专门处理float类型的构造函数
    type_wrap(typename enable_if<is_same<float, T>::value, T>::type&& rrT)
        : value(std::move(rrT)) {
        cout << "The wrapped type is float, value: " << value << endl;
    }

    // 扩展:专门处理std::string类型的构造函数
    type_wrap(typename enable_if<is_same<string, T>::value, T>::type&& rrT)
        : value(std::move(rrT)) {
        cout << "The wrapped type is std::string, value: " << value << endl;
    }

    // 通用构造函数,处理未专门重载的其他类型
    template<typename U = T, typename = typename enable_if<
        !is_same<U, int>::value && 
        !is_same<U, float>::value && 
        !is_same<U, string>::value
    >::type>
    type_wrap(U&& val) : value(std::forward<U>(val)) {
        cout << "The wrapped type is " << typeid(T).name() << ", value: " << value << endl;
    }
};

int main() {
    // 测试不同类型的包装
    type_wrap<int> int_wrap(42);
    type_wrap<float> float_wrap(3.14f);
    type_wrap<string> str_wrap("Hello World");
    type_wrap<double> double_wrap(2.718); // 触发通用构造函数

    return 0;
}

接下来拆解几个关键部分,帮你理解为什么要这么写:

  • 核心成员变量:给type_wrap添加了T value;,这是用来存储被包装的类型实例的基础,没有它包装结构体就失去了意义。
  • SFINAE构造函数重载:每个针对特定类型的构造函数都用enable_if<is_same<目标类型, T>::value, T>::type限定参数类型。简单说,只有当模板参数T和我们指定的类型(比如int)完全匹配时,这个构造函数才会被编译器识别,否则会被自动忽略——这就是SFINAE(Substitution Failure Is Not An Error)的核心作用,实现编译期的函数重载筛选。
  • 类型信息输出:对于明确指定的类型(比如int、float),直接输出清晰的类型名称;对于其他未专门处理的类型,用typeid(T).name()获取编译器提供的类型标识(注意这个标识格式是编译器相关的,比如GCC里int会显示i,MSVC里会显示int)。
  • 通用构造函数:用额外的模板参数和enable_if排除已经有专门重载的类型,确保所有其他类型都能正常构造,同时输出对应的类型和值信息。这里用std::forward实现完美转发,保证参数传递的效率。
  • 移动语义:构造函数使用右值引用(&&)并配合std::move传递参数,避免不必要的拷贝操作,提升代码效率。

运行这段代码后,你会看到类似这样的输出(不同编译器可能略有差异):

The wrapped type is int, value: 42
The wrapped type is float, value: 3.14
The wrapped type is std::string, value: Hello World
The wrapped type is d, value: 2.718

内容的提问来源于stack exchange,提问作者user9196120

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:49:48