如何比较 C++ 中的类型?
How can I compare types in C++?
有没有办法在 C++ 中比较变量类型?例如,我想要这样工作的东西:(使用伪语言)
template <class T> void checkType(T variable) {
if(type_of(T) == int) cout << "The variable is of type int.\n";
}
编辑 1:我尝试使用 is_same,但它在 Xcode 中不起作用...但是当我尝试使用脚本包在 Atom 中的以下简单代码中使用它时它运行。
#include <iostream>
using namespace std;
template <class T> void print(T value) {
if(is_same<T, char> :: value) cout << "char\n";
if(is_same<T, int> :: value) cout << "int\n";
if(is_same<T, string> :: value) cout << "string\n";
}
int main() {
string var1;
int var2;
char var3;
print(var1);
print(var2);
print(var3);
return 0;
}
编辑 2:我将不起作用的代码放在这里。现在我试着评论关于字符串的部分,代码适用于 int 和 char。
template <class keytype, class attrtype>
void LinkedList <keytype, attrtype> :: insert(keytype k, attrtype a) {
LinkedList <keytype, attrtype> :: position iter = l.head();
if(is_same<keytype, int> :: value) {
while(iter != NULL and k > iter -> key) {
iter = l.next(iter);
}
l.insert(iter, k, a);
}
else if(is_same<keytype, char> :: value) {
while(iter != NULL and tolower(k) > tolower(iter -> key)) {
iter = l.next(iter);
}
l.insert(iter, k, a);
}
//Whatever type I pass by the template in 'keytype' enters this if statement
else if(is_same<keytype, string> :: value) {
bool node_filled = false;
if(iter == NULL) {
l.insert(iter, k, a);
node_filled = true;
}
else {
unsigned long rif = 0;
int i = 0;
while(!node_filled and iter != NULL) {
if(tolower(iter -> key.at(0)) > tolower(k.at(0))) {
l.insert(iter, k, a);
node_filled = true;
}
else if(tolower(iter -> key.at(0)) < tolower(k.at(0))) {
iter = l.next(iter);
}
else if(tolower(iter -> key.at(0)) == tolower(k.at(0))) {
if(k.size() > iter -> key.size())
rif = iter -> key.size();
else
rif = k.size();
while((i < rif - 1) and (k.at(i) == iter -> key.at(i))) {
i ++;
}
if(tolower(iter -> key.at(i)) > tolower(k.at(i))) {
l.insert(iter, k, a);
node_filled = true;
}
else if(tolower(iter -> key.at(i)) == tolower(k.at(i))) {
if(k.size() < iter -> key.size()) {
l.insert(iter, k, a);
node_filled = true;
}
else {
iter = l.next(iter);
}
}
else if(tolower(iter -> key.at(i)) < tolower(k.at(i))) {
iter = l.next(iter);
}
}
}
if(!node_filled) {
l.insert(NULL, k, a);
}
}
}
}
你可以试试这个:
template <class T> void checkType(T variable) {
switch(sizeof(T)){
case sizeof(int) :
cout << "The variable is of type int.\n";
break;
case sizeof(char):
cout << "The variable is of type char.\n";
break;
}
}
观察:如果您有一个向量,则必须对其进行特殊处理,例如将它的 sizeof int 开关参数除以向量的分配次数。
这对我有用。
#include <iostream>
#include <string>
#include <type_traits>
using namespace std;
template <class T>
void print(T value) {
if (is_same<T, char>::value) cout << "char\n";
if (is_same<T, int>::value) cout << "int\n";
if (is_same<T, string>::value) cout << "string\n";
}
int main() {
string var1;
int var2;
char var3;
print(var1);
print(var2);
print(var3);
return 0;
}
在C++17中,可以使用if constexpr
让编译器生成更优化的代码生成器:
#include <iostream>
#include <string>
#include <type_traits>
using namespace std;
template <class T>
void print(T value) {
if constexpr (is_same_v<T, char>) cout << "char\n";
if constexpr (is_same_v<T, int>) cout << "int\n";
if constexpr (is_same_v<T, string>) cout << "string\n";
}
int main() {
string var1;
int var2;
char var3;
print(var1);
print(var2);
print(var3);
return 0;
}
查看 EDIT 2 中的代码,您可能想在那里使用 if constexpr
(假设是 C++17 兼容的编译器)。这里的问题是,通常编译器需要为 if 语句的所有分支检查你的代码,即使逻辑上只有一个分支可能被用于给定的模板实例化。
if constexpr
放宽了这个要求:未采用的分支被“丢弃”,这意味着如果不采用分支,则不会实例化依赖于模板参数的值。这意味着它永远不会尝试做,例如,当 keytype
是 int
时,k.at(0)
,因为如果是这种情况,我们将不会进入该分支。
假设您的编译器支持 C++17(并且该标准已启用!),将代码中的所有 if
替换为 if constexpr
应该可以解决此特定问题。
在 C++ 中有 typeid()
运算符,它 returns 一个 std::type_info
,可以有多种使用方式。
你这样使用std::type_info::hash_code()
:
template<typename T>
void print()
{
if (typeid(T).hash_code() == typeid(char).hash_code())
std::cout << "char\n"
else if (typeid(T).hash_code() == typeid(int).hash_code())
std::cout << "int\n"
else if (typeid(T).hash_code() == typeid(std::string).hash_code())
std::cout << "std::string\n"
}
或者,您可以像这样使用 std::type_info::name()
:
template<typename T>
void print()
{
std::cout << typeid(T) << '\n';
}
请注意后者,如果你输入类似 std::string
的内容,你最终会得到类似 class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
的输出。那只是因为 std::string
是 using
为 class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
定义的。
编辑:我忘了说,你需要 #include <typeinfo>
才能使用 std::type_info
。
有没有办法在 C++ 中比较变量类型?例如,我想要这样工作的东西:(使用伪语言)
template <class T> void checkType(T variable) {
if(type_of(T) == int) cout << "The variable is of type int.\n";
}
编辑 1:我尝试使用 is_same,但它在 Xcode 中不起作用...但是当我尝试使用脚本包在 Atom 中的以下简单代码中使用它时它运行。
#include <iostream>
using namespace std;
template <class T> void print(T value) {
if(is_same<T, char> :: value) cout << "char\n";
if(is_same<T, int> :: value) cout << "int\n";
if(is_same<T, string> :: value) cout << "string\n";
}
int main() {
string var1;
int var2;
char var3;
print(var1);
print(var2);
print(var3);
return 0;
}
编辑 2:我将不起作用的代码放在这里。现在我试着评论关于字符串的部分,代码适用于 int 和 char。
template <class keytype, class attrtype>
void LinkedList <keytype, attrtype> :: insert(keytype k, attrtype a) {
LinkedList <keytype, attrtype> :: position iter = l.head();
if(is_same<keytype, int> :: value) {
while(iter != NULL and k > iter -> key) {
iter = l.next(iter);
}
l.insert(iter, k, a);
}
else if(is_same<keytype, char> :: value) {
while(iter != NULL and tolower(k) > tolower(iter -> key)) {
iter = l.next(iter);
}
l.insert(iter, k, a);
}
//Whatever type I pass by the template in 'keytype' enters this if statement
else if(is_same<keytype, string> :: value) {
bool node_filled = false;
if(iter == NULL) {
l.insert(iter, k, a);
node_filled = true;
}
else {
unsigned long rif = 0;
int i = 0;
while(!node_filled and iter != NULL) {
if(tolower(iter -> key.at(0)) > tolower(k.at(0))) {
l.insert(iter, k, a);
node_filled = true;
}
else if(tolower(iter -> key.at(0)) < tolower(k.at(0))) {
iter = l.next(iter);
}
else if(tolower(iter -> key.at(0)) == tolower(k.at(0))) {
if(k.size() > iter -> key.size())
rif = iter -> key.size();
else
rif = k.size();
while((i < rif - 1) and (k.at(i) == iter -> key.at(i))) {
i ++;
}
if(tolower(iter -> key.at(i)) > tolower(k.at(i))) {
l.insert(iter, k, a);
node_filled = true;
}
else if(tolower(iter -> key.at(i)) == tolower(k.at(i))) {
if(k.size() < iter -> key.size()) {
l.insert(iter, k, a);
node_filled = true;
}
else {
iter = l.next(iter);
}
}
else if(tolower(iter -> key.at(i)) < tolower(k.at(i))) {
iter = l.next(iter);
}
}
}
if(!node_filled) {
l.insert(NULL, k, a);
}
}
}
}
你可以试试这个:
template <class T> void checkType(T variable) {
switch(sizeof(T)){
case sizeof(int) :
cout << "The variable is of type int.\n";
break;
case sizeof(char):
cout << "The variable is of type char.\n";
break;
}
}
观察:如果您有一个向量,则必须对其进行特殊处理,例如将它的 sizeof int 开关参数除以向量的分配次数。
这对我有用。
#include <iostream>
#include <string>
#include <type_traits>
using namespace std;
template <class T>
void print(T value) {
if (is_same<T, char>::value) cout << "char\n";
if (is_same<T, int>::value) cout << "int\n";
if (is_same<T, string>::value) cout << "string\n";
}
int main() {
string var1;
int var2;
char var3;
print(var1);
print(var2);
print(var3);
return 0;
}
在C++17中,可以使用if constexpr
让编译器生成更优化的代码生成器:
#include <iostream>
#include <string>
#include <type_traits>
using namespace std;
template <class T>
void print(T value) {
if constexpr (is_same_v<T, char>) cout << "char\n";
if constexpr (is_same_v<T, int>) cout << "int\n";
if constexpr (is_same_v<T, string>) cout << "string\n";
}
int main() {
string var1;
int var2;
char var3;
print(var1);
print(var2);
print(var3);
return 0;
}
查看 EDIT 2 中的代码,您可能想在那里使用 if constexpr
(假设是 C++17 兼容的编译器)。这里的问题是,通常编译器需要为 if 语句的所有分支检查你的代码,即使逻辑上只有一个分支可能被用于给定的模板实例化。
if constexpr
放宽了这个要求:未采用的分支被“丢弃”,这意味着如果不采用分支,则不会实例化依赖于模板参数的值。这意味着它永远不会尝试做,例如,当 keytype
是 int
时,k.at(0)
,因为如果是这种情况,我们将不会进入该分支。
假设您的编译器支持 C++17(并且该标准已启用!),将代码中的所有 if
替换为 if constexpr
应该可以解决此特定问题。
在 C++ 中有 typeid()
运算符,它 returns 一个 std::type_info
,可以有多种使用方式。
你这样使用std::type_info::hash_code()
:
template<typename T>
void print()
{
if (typeid(T).hash_code() == typeid(char).hash_code())
std::cout << "char\n"
else if (typeid(T).hash_code() == typeid(int).hash_code())
std::cout << "int\n"
else if (typeid(T).hash_code() == typeid(std::string).hash_code())
std::cout << "std::string\n"
}
或者,您可以像这样使用 std::type_info::name()
:
template<typename T>
void print()
{
std::cout << typeid(T) << '\n';
}
请注意后者,如果你输入类似 std::string
的内容,你最终会得到类似 class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
的输出。那只是因为 std::string
是 using
为 class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
定义的。
编辑:我忘了说,你需要 #include <typeinfo>
才能使用 std::type_info
。