c++ 将typeid与模板一起使用[重复]

7gs2gvoe  于 2023-05-24  发布在  其他
关注(0)|答案(2)|浏览(157)

此问题已在此处有答案

Difference between "if constexpr()" Vs "if()"(2个答案)
7小时前关闭

template<class T>
inline T Library<T>::get_isbn()
{
    T temp;
    cout << "Enter the name/no:" << endl;
    cin >> temp;
    string ka;
    if (typeid(temp) == typeid(ka))
    {
        while (islower(temp[0]))
        {
            cout << " Pls enter the using the first letter as capital" << endl;
            cin >> temp;
        }
    }
}
return temp;
}

我正在创建一个模板类,它可以接受integer或string作为模板参数,当我创建一个类的对象时,将T作为string,它将进入循环,一切正常。但是当我创建一个以int为模板参数的对象时,它给了我以下两个错误:
错误C1903:无法从以前的错误中恢复;停止编译
错误C2228:“.at”的左侧必须具有类/结构/联合
我希望如果参数是string,那么只有检查第一个字母是大写的代码应该运行,否则当我将模板参数作为int时,它不应该检查第一个字母。

inn6fuwd

inn6fuwd1#

C++中的if始终(语义上)是一个运行时决策。它 * 可能 * 会在编译时被编译器计算,而未使用的分支会被丢弃。但它 * 可能 * 并不意味着它 * 必须 *。您仍然需要确保所有分支都包含有效代码。
在这个例子中,如果temp是整数,则表达式temp[0]是病态的。最简单的解决方案是在泛型函数中调用一个重载函数--注意:通过引入一个typeid分支,你的算法本质上不再是通用的,它需要对某些类型进行特殊处理。

template<class T>
void get_isbn_impl(T&)
{
    // default implementation
}

void get_isbn_impl(string& str)
{
    // special version for `string`
    while (islower(str[0]))
    {
        cout << " Pls enter the using the first letter as capital" << endl;
        cin >> str;
    }
}

template<class T>
inline T Library<T>::get_isbn()
{
    T temp;
    cout << "Enter the name/no:" << endl;
    cin >> temp;

    get_isbn_impl(temp);

    return temp;
}

也可以专门化Library<string>(整个类)或仅专门化Library<string>::get_isbn

5lhxktic

5lhxktic2#

typeid不是constexpr,因此在编译阶段不会影响模板内容。所有的东西都必须编译。
C++ 17引入了if constexpr语句,所以可以用类似于你的例子的方式定义一个函数:

#include <string>
#include <cctype>
#include <iostream>
#include <type_traits>

template<class T>
inline T get_isbn()
{
    T temp;
    std::cout << "Enter the name/no:" << std::endl;
    std::cin >> temp;
    std::string ka;
    // if (typeid(temp) == typeid(ka)) // It is not a constexpr.
    
    // if constexpr compiles only when condition is met.
    
    // Passing types directly to std::is_same
    // if constexpr (std::is_same<T, std::string>::value)
    
    // Deducing types using decltype()
    if constexpr (std::is_same<decltype(temp), decltype(ka)>::value)
    {
        while (std::islower(temp[0]))
        {
            std::cout << " Pls enter the using the first letter as capital" << std::endl;
            std::cin >> temp;
        }
    }
    return temp;
}

int main()
{
    const auto isbn_int = get_isbn<int>();
    std::cout << "The ISBN<int> is: ["<< isbn_int << "]" << std::endl;
    
    const auto isbn_string = get_isbn<std::string>();
    std::cout << "The ISBN<string> is: ["<< isbn_string << "]" << std::endl;
    return 0;
}

// Sample input/output:
// Enter the name/no:
// 123
// The ISBN<int> is: [123]
// Enter the name/no:
// My-ISBN-Number 
// The ISBN<string> is: [My-ISBN-Number]

在C++17之前,必须使用模板专门化,如@dyp所述。

相关问题