运行时确定 C++ 的类型
我想知道是否可以将类型确定为 C++ 中的运行时信息。
(1)虽然我的问题很笼统,但为了简单起见,我将从一个简单的例子开始:
#include <stdio.h>
#include <iostream>
#include <cstring>
using namespace std;
int main(int argc, char * argv[])
{
if (strcmp(argv[1], "int")==0)
{
int t = 2;
}else if (strcmp(argv[1], "float")==0)
{
float t = 2.2;
}
cout << t << endl; // error: ‘t’ was not declared in this scope
return 0;
}
对于这个例子,有两个问题:
(a)“argv[1] to t”是错误的,但是可以将 type info in C 字符串argv[1] 能否转换为实际类型关键字?所以我们不需要通过 if-else 子句和 strcmp 检查每种类型。
(b) 如何使在 if 子句的局部范围内定义的变量 t 在外部仍然有效。即如何将局部变量“导出”到其作用域之外?
(2)一般来说,不具体针对上面的简单例子,运行时判断类型的常用方法有哪些?在我看来,可能有一些方法:
(a)可以将对从类型定义的变量的处理放在其定义的同一范围内。例如
#include <stdio.h>
#include <iostream>
#include <cstring>
using namespace std;
int main(int argc, char * argv[])
{
if (strcmp(argv[1], "int")==0)
{
int t = 2;
cout << t << endl;
}else if (strcmp(argv[1], "float")==0)
{
float t = 2.2;
cout << t << endl;
}
return 0;
}
,可能使用模板函数来使各种类型的公共代码可重用。
(b) 或者可以使用抽象类类型和多态性来间接导出定义,但我不确定具体如何导出。
感谢您的建议!
I am wondering if type can be determined as runtime information in C++.
(1) Although my question is quite general, for simplicity, I will start from a simple example:
#include <stdio.h>
#include <iostream>
#include <cstring>
using namespace std;
int main(int argc, char * argv[])
{
if (strcmp(argv[1], "int")==0)
{
int t = 2;
}else if (strcmp(argv[1], "float")==0)
{
float t = 2.2;
}
cout << t << endl; // error: ‘t’ was not declared in this scope
return 0;
}
For this example, there are two questions:
(a) "argv[1] to t" is wrong, but can the type info in the C string argv[1] be converted to the actual type keyword? So we don't need to check for every type by if-else clause and strcmp.
(b) how to make variable t defined inside the local scope of the if clause still valid outside. i.e how to "export" a local variable to the outside of its scope?
(2) Generally speaking, not specific to the simple example above, what are the usual ways to runtime determine types? It seems to me that there might be some ways:
(a) one can put the processing of the variable defined from the type inside the same scope its definition. e.g.
#include <stdio.h>
#include <iostream>
#include <cstring>
using namespace std;
int main(int argc, char * argv[])
{
if (strcmp(argv[1], "int")==0)
{
int t = 2;
cout << t << endl;
}else if (strcmp(argv[1], "float")==0)
{
float t = 2.2;
cout << t << endl;
}
return 0;
}
And possibly use template function to make the common code for various types reusable.
(b) or one may use abstract class type and polymorphism to indirectly export the definition out, but I am not sure how exactly.
Thanks for your advice!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
1a:不,类型不是 C++ 中的对象或值(例如,在 Python 中)。但是,您可以使用由 argv[1] 的值选择的各种值。
1b:抱歉,不能这么做。
2:dynamic_cast和typeid(都是运算符)是该语言当前提供的唯一用于查询类型的工具(这并不罕见,大多数语言都很少有专门的工具),并且通常不鼓励仅使用它们来查询类型,具体取决于根据情况(在其他语言中也并不罕见)。
2a:是的,因为这是简单、明显的并且可以在这里工作 - 没有理由使用其他任何东西,但由于它是示例代码,让我们假设您需要不同的解决方案。您可以调用在正确类型上实例化的函数模板,但由于这与 2a 的其余部分几乎相同,因此我不会详细介绍它。
2b:使用子类模板的示例,只是因为它很方便:
使用:
这开始将两种类型合并为一种类型,并且它们都呈现相同的接口,即 Base,在这里。但是,这并不适合所有解决方案,以及 boost.variant 可能会更好,特别是当所需的各种类型数量很少并且提前已知时。
1a: No, types are not objects or values in C++ (as they are, for example, in Python). You can, however, use various values selected by the value of argv[1].
1b: Sorry, just can't do that.
2: dynamic_cast and typeid (both operators) are the only tools currently provided by the language to query type (not unusual, most languages have very few, but dedicated, tools for that), and using them solely to query type is often discouraged depending on situation (also not unusual among other languages).
2a: Yes, and as that is the simple, obvious, and works here—there's no reason to use anything else, but as it's example code, let's assume you need a different solution. You could call a function template instantiated on the right type, but as this is pretty much the same thing as the rest of 2a, I don't go into it.
2b: Example using a subclass template, just because it's handy:
Use:
This is starting to merge the two types into one type, and they both present the same interface, Base, here. However, this doesn't lend itself well to every solution, and a variant such as boost.variant can be better, particularly when the various types required are small in number and known well in advance.
您需要一个能够存储不同类型的值的类。如果没有联合,Boost 的变体类将是正确的选择。
You need a class that's capable of storing a value of different types. Short from a union, Boost's variant class would be the proper choice.
查看 Boost.Variant。
Check out Boost.Variant.