簡體   English   中英

如何比較 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 中使用 Script 包運行的以下簡單代碼中使用它時。

#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);
            }
        }
    }
}

查看 EDIT 2 中的代碼,您可能希望在那里使用if constexpr (假設編譯器符合 C++17)。 這里的問題是,通常編譯器需要對 if 語句的所有分支的代碼進行語法檢查,即使邏輯上對於給定的模板實例化可能只采用一個分支。

if constexpr放寬此要求:未采用的分支被“丟棄”,這意味着如果未采用分支,則不會實例化依賴於模板參數的值。 這意味着它永遠不會嘗試執行,例如,當keytypeintk.at(0) ,因為如果是這種情況,我們將不會進入該分支。

假設您的編譯器支持 C++17(並且該標准已啟用!),將代碼中的所有if替換為if constexpr應該可以解決此特定問題。

這對我有用。

#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;
}

現場演示

在 C++ 中有typeid()運算符,它返回一個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> > for一個輸出。 這完全是因為std::stringusing定義class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >

編輯:我忘了說,你需要一個#include <typeinfo>來使用std::type_info

你可以試試這個:

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;
    }
}

觀察:如果您有一個向量,則必須對其進行特殊處理,例如將 switch 參數的 sizeof int 除以向量的分配數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM