簡體   English   中英

String Literal的模板參數演繹

[英]Template Argument Deduction from String Literal

我目前正在考慮如何最好地將通用類型的模板約束到std::sting以及字符串文字。 因此,我使用std::is_same導出的類型與所需類型進行std::is_same 如果是std::string則可以立即使用。 對於字符串文字,意思是char const數組,它只有在我對類型使用std::decay然后將結果與char const *類型進行比較時才有效。 如果我直接is_same導出的類型與我認為的類型進行比較,則is_same返回false,如下面的示例代碼所示。

template <class TYPE>
void function(TYPE&& parameter)
{
  //this doesn't work as expected
  std::cout << typeid(TYPE).name() << " : " << typeid(char const [5]).name() << std::endl;
  std::cout << std::is_same<char const [5], TYPE>::value << std::endl;
  //this works as expected
  std::cout << typeid(std::decay_t<TYPE>).name() << " : " << typeid(char const *).name() << std::endl;
  std::cout << std::is_same<char const *, std::decay_t<TYPE>>::value << std::endl;
}

int main(int argc, char** argv)
{
  function("name");
  return 0;
}

生成的輸出如下:

char const [5] : char const [5]
0
char const * __ptr64 : char const * __ptr64
1

現在,我想知道的是,為什么is_same在第一種情況下返回false,即使類型看起來是相同的。

我能想到的唯一可能的解釋是,在函數std::is_same類似於std::decay的轉換應用於該類型(例如函數調用)。 但是,這種轉變也會發生在另一種類型中,產生相同的結果,從而導致平等。

字符串文字不作為char const [N]傳遞值,而是作為char const (&)[N] 引用

這適合我:

std::cout << std::is_same<char const (&)[5], TYPE>::value << std::endl;

請注意這里

1)引用表示類型類型的std::type_info對象。 如果type是引用類型,則結果引用表示引用類型的std::type_info對象

您可以輕松驗證is_same是否以與type_info相同的方式丟棄引用,例如通過檢查

std::is_same<int&, int>::value == false

這解釋了為什么typeid名稱相同,但is_same測試仍然失敗。

使用gcc自定義功能:

template < class T >
constexpr std::string type_name()
{
    std::string p = __PRETTY_FUNCTION__;
    return p.substr( 43 + 10, p.length() - 100 - 1 - 10 );
}

並將其添加到您的代碼中:

std::cout << type_name<TYPE>() << " : " << type_name<char const [5]>() << std::endl;

結果是:

A5_c : A5_c
0
const char (&)[5] : const char [5]

所以你需要在TYPE上使用std::remove_reference

這可能是編譯器的錯誤。 編譯器在編譯時生成由typeid給出的類型對象。 編譯器不會為每個長度(0到2 ** n)編譯數組類型,因此它在需要時編譯它們,並且它可能“忘記”重復。 嘗試使用一個特殊的模板,在其中分隔所包含類型的長度。 這不是類型,但您可以檢查它是否與另一個相等。

    template<class T, size_t size> 
struct array_t{};

    template <class T, size_t size>
void function(T[size] parameter) {
    std::cout << typeid(array_t<T, size>).name() << " : " << typeid(array_t<char, 5>).name() << std::endl;
    std::cout << std::is_same<array_t<T, size>, array_t<char, 5>>::value << std::endl;
};

暫無
暫無

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

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