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

typedef类型别名运行时识别问题:如何区分同基类型的别名?

问题:区分typedef定义的同基础类型别名

你的C++代码如下:

#include <iostream>
#include <type_traits>

typedef char stringType1;
typedef char stringType2;

typedef enum
{
    myType_noType,  // 0
    myType_stringType1, // 1
    myType_stringType2  // 2
} MyDataType_t;

//TYPE CHECK
template <typename T>
constexpr MyDataType_t TYPE_NAME(T x)
{
    if constexpr (std::is_same<decltype(x),stringType1>::value){return myType_stringType1;}

    if constexpr (std::is_same<decltype(x),stringType2>::value){return myType_stringType2;}

    return myType_noType;
}

template <typename T>
MyDataType_t myFunction(T *value)
{
    return TYPE_NAME(*value);
}

int main()
{
    std::cout<<"Hello World"<< std::endl;

    stringType1 var1;
    stringType2 var2;

    MyDataType_t aTypeId = myFunction(&var1);    
    std::cout << aTypeId << std::endl;
    aTypeId = myFunction(&var2);    
    std::cout << aTypeId << std::endl;

    return 0;
}

运行结果:

Hello World
1
1

问题原因

typedef只是给已有类型起别名,stringType1和stringType2本质上都是char类型,编译器不会把它们视为独立的类型。因此std::is_same会判定两者完全相同,导致TYPE_NAME函数无法区分,最终返回同一个枚举值。

解决方案

要区分这两种类型,必须创建真正独立的类型,以下是两种可行方案:

方案1:用结构体包装基础类型

通过结构体封装char,生成完全独立的新类型,编译期就能明确区分:

#include <iostream>
#include <type_traits>

// 用结构体包装char,生成不同的类型
struct stringType1 { char value; };
struct stringType2 { char value; };

enum class MyDataType_t {
    myType_noType,
    myType_stringType1,
    myType_stringType2
};

template <typename T>
constexpr MyDataType_t TYPE_NAME(const T& x) {
    if constexpr (std::is_same_v<T, stringType1>) {
        return MyDataType_t::myType_stringType1;
    } else if constexpr (std::is_same_v<T, stringType2>) {
        return MyDataType_t::myType_stringType2;
    } else {
        return MyDataType_t::myType_noType;
    }
}

template <typename T>
MyDataType_t myFunction(const T* value) {
    return TYPE_NAME(*value);
}

int main() {
    std::cout << "Hello World" << std::endl;

    stringType1 var1;
    stringType2 var2;

    auto aTypeId = myFunction(&var1);    
    std::cout << static_cast<int>(aTypeId) << std::endl; // 输出1
    aTypeId = myFunction(&var2);    
    std::cout << static_cast<int>(aTypeId) << std::endl; // 输出2

    return 0;
}

方案2:利用模板别名+标签类型

如果需要保留类似typedef的语法,同时区分类型,可以结合模板别名和标签类型:

#include <iostream>
#include <type_traits>

// 定义标签类型,用于区分
struct Tag1 {};
struct Tag2 {};

// 模板别名,绑定标签和char类型
template <typename Tag>
using TaggedChar = char;

using stringType1 = TaggedChar<Tag1>;
using stringType2 = TaggedChar<Tag2>;

enum class MyDataType_t {
    myType_noType,
    myType_stringType1,
    myType_stringType2
};

// 通过函数重载区分不同标签的类型
constexpr MyDataType_t TYPE_NAME(TaggedChar<Tag1>) {
    return MyDataType_t::myType_stringType1;
}

constexpr MyDataType_t TYPE_NAME(TaggedChar<Tag2>) {
    return MyDataType_t::myType_stringType2;
}

template <typename T>
constexpr MyDataType_t TYPE_NAME(T) {
    return MyDataType_t::myType_noType;
}

template <typename T>
MyDataType_t myFunction(T* value) {
    return TYPE_NAME(*value);
}

int main() {
    std::cout << "Hello World" << std::endl;

    stringType1 var1;
    stringType2 var2;

    auto aTypeId = myFunction(&var1);    
    std::cout << static_cast<int>(aTypeId) << std::endl; // 输出1
    aTypeId = myFunction(&var2);    
    std::cout << static_cast<int>(aTypeId) << std::endl; // 输出2

    return 0;
}

说明

  • 方案1的结构体包装是最直观的方式,每个结构体都是独立类型,使用时需要通过.value访问底层char。
  • 方案2的模板别名+标签类型,既保留了char的所有特性(可以直接当作char使用),又能让编译器识别为不同类型,适合需要兼容原有char操作的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 13:58:32