C++ 使用模板C动态设置struct++;

C++ 使用模板C动态设置struct++;,c++,templates,dynamic,struct,C++,Templates,Dynamic,Struct,我正在尝试使用模板动态设置struct中的字段。我已经在代码中编写了这两种方法。这两种方法都不起作用,即没有名为t.age的成员。如何动态设置字段?感谢您的帮助 #include <iostream> using namespace std; struct hello { string name; }; struct bye { int age; }; template <typename T> void printHello(

我正在尝试使用模板动态设置struct中的字段。我已经在代码中编写了这两种方法。这两种方法都不起作用,即
没有名为t.age的成员。
如何动态设置字段?感谢您的帮助

#include <iostream> 

using namespace std; 

struct hello { 
    string name; 
}; 

struct bye { 
    int age; 
}; 

template <typename T>  
void printHello(string key) { 
    T t;  
    if (key == "HELLO") { 
        t.name = "John"; 
    }   
    else { 
        t.age = 0;  
    }   
} 

template <typename T>
T setStruct(T t) {   
    if (typeid(t) == typeid(hello)) {
        t.name = "John";
    } 
    else {
        t.age = 0;
    }
    return t; 
}

int main() { 
    //printHello<hello>("HELLO"); // ERROR: no member named t.age 
    hello h;
    h = setStruct(h); // ERROR: no member named t.age
    return 0;
}
#包括
使用名称空间std;
结构hello{
字符串名;
}; 
结构bye{
智力年龄;
}; 
样板
void printHello(字符串键){
T;
如果(key==“HELLO”){
t、 name=“John”;
}   
否则{
t、 年龄=0;
}   
} 
样板
T setStruct(T){
if(typeid(t)=typeid(hello)){
t、 name=“John”;
} 
否则{
t、 年龄=0;
}
返回t;
}
int main(){
//printHello(“HELLO”);//错误:没有名为t.age的成员
你好,h;
h=setStruct(h);//错误:没有名为t.age的成员
返回0;
}

printHello
将永远无法工作,因为您希望对运行时字符串值执行编译时分支

setStruct
更接近于一种可能的解决方案,但同样,
typeid
返回一个运行时值-您需要一个编译时分支谓词,以便有条件地编译
.name
.age
访问

在C++17中,如果constexpr和
std::is_v
相同,则可以使用
轻松解决此问题:

template <typename T>
T setStruct(T t) {   
    if constexpr(std::is_same_v<T, hello>) {
        t.name = "John";
    } 
    else {
        t.age = 0;
    }
    return t; 
}
我正在尝试使用模板动态设置struct中的字段

我认为你使用了错误的策略。您可以使用简单的重载并完全避免与函数模板相关的问题

hello setStruct(hello h)
{
   h.name = "John";
   return h;
}

bye setStruct(bye b)
{
   b.age = 0;
   return b;
}
函数模板只有在大多数代码与类型无关时才有价值。

在C++11中可以使用
type\u traits

下面是您如何处理问题的示例:

#include <string>
#include <type_traits>

struct A {
  std::string name;
};

struct B {
  int age;
};

template<typename T>
typename std::enable_if<std::is_same<T, A>::value>::type
setStruct(T* t) {
  t->name = "This is a string";
}

template<typename T>
typename std::enable_if<std::is_same<T, B>::value>::type
setStruct(T* t) {
  t->age = 47;
}

int main(int argc, char *argv[]) {
  A a;
  B b;
  setStruct(&a);
  setStruct(&b);
  return 0;
}
#包括
#包括
结构A{
std::字符串名;
};
结构B{
智力年龄;
};
样板
typename std::enable_if::type
设置结构(T*T){
t->name=“这是一个字符串”;
}
样板
typename std::enable_if::type
设置结构(T*T){
t->年龄=47岁;
}
int main(int argc,char*argv[]){
A A;
B B;
setStruct&a;
设置结构(&b);
返回0;
}
嗯,这个设计是个糟糕的选择。它使代码不可读,并且
可以很容易地避免使用其他模式:如多态类、重载或重构数据结构。

应该是动态模式和模板通常不匹配的方式,由于在运行时没有模板,
printHello
中的代码同时使用
T::name
T::age
,因此它只适用于同时具有这两个模板的类型。如果我想在struct中获取值,该怎么办?相同的重载策略有效吗?@pseudo:yes-您应该熟悉重载,因为它是语言的核心。@pseudo Vittorio提出的解决方案是一种先进的、专门的功能。你的
setStruct
函数让我觉得你应该先学习基础知识,比如“构造函数”是什么。然后是重载、继承、多态等。
#include <string>
#include <type_traits>

struct A {
  std::string name;
};

struct B {
  int age;
};

template<typename T>
typename std::enable_if<std::is_same<T, A>::value>::type
setStruct(T* t) {
  t->name = "This is a string";
}

template<typename T>
typename std::enable_if<std::is_same<T, B>::value>::type
setStruct(T* t) {
  t->age = 47;
}

int main(int argc, char *argv[]) {
  A a;
  B b;
  setStruct(&a);
  setStruct(&b);
  return 0;
}