C++ 使用模板C动态设置struct++;
我正在尝试使用模板动态设置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(
没有名为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;
}