如何在模板类函数中分配struct值?

use*_*126 2 c++ factory visual-c++

我有一堆结构需要添加到我的矢量并给它们一些默认值.

  1. 结构是外部的,我无法改变它们.
  2. 在分配这些值时,为了方便起见,我需要查看struct成员名称.
  3. 为方便起见,我需要在同一个地方直观地显示所有默认值.
  4. 编译器当前优化了myClass :: addStruct()中未使用的if分支 - 这正是我想要的.

问:可以用更好/更简单的方式完成吗?

编辑我没有C++ 17

//外部结构

typedef struct A {
    int member1;
    float member2;
    char *member3;
    // ...
} A;

typedef struct B {
    double member5;
    float member3;
    int *member4;
    // ...
} B;

typedef struct C {
    char* member5;
    char* member2;
    float *member3;
    // ...
} C;

...

template <class T>
void myClass::addStruct(std::vector<T> &vp)
{
    void *sp = nullptr;
    if(std::is_same<T, A>::value) {
        A s{};
        s.member1 = 2;
        s.member3 = "whatever";
        sp = &s;
    }
    else if(std::is_same<T, B>::value) {
        B s{};
        s.member4 = nullptr;
        s.member3 = 3.1f;
        sp = &s;
    }
    else if(std::is_same<T, C>::value) {
        C s{};
        s.member2 = "whenever";
        sp = &s;
    }
/*  else if() {
    }
    else if() {
    } ...
*/

    if(sp == nullptr) {
        // print error
        return;
    }

    vp.push_back(*(reinterpret_cast<T*>(sp)));
}

// usage

addStruct<A>(...);
addStruct<A>(...);
addStruct<B>(...);
addStruct<C>(...);
Run Code Online (Sandbox Code Playgroud)

Tra*_*s3r 8

  1. 像这样的代码甚至不应该编译,除非你使用constexpr(又名"静态if").它只是"有效",因为你破坏了类型系统(整个void*和reinterpret_cast舞蹈).类型别名规则适用.
  2. 您正在获取已超出范围的对象的地址.那是未定义的行为,现在工作时可能会在更改代码或编译器或只是编译器版本时随时中断.
  3. 如果你真的想要使用该代码,为什么不为不同的类型创建非模板重载?方式更容易.

  • 它编译没有说什么 - 你用`void*`来逃避类型系统.它没有任何作用 - 未定义的行为还包括"一切正常(现在)"的可能性.在这种情况下,很明显你在UB的土地上:`sp`指向一个堆栈变量(例如`A s`),当你执行`push_back`时,它已经超出了范围. (3认同)