将类型标识与模板一起使用
Using typeid with templates
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;
}
我正在创建一个模板类,它可以将整数或string
作为模板参数,当我创建T
作为string
的类对象时,它会进入循环并且一切正常。但是当我使用 int
作为模板参数创建一个对象时,它会给我以下两个错误:
错误C1903:无法从以前的错误中恢复;正在停止 汇编
错误 C2228:".at"的左侧必须具有类/结构/联合
我希望如果传递的参数是string
,那么只有检查第一个字母是大写的代码应该运行,否则当我将模板参数作为int
时,它不应该检查第一个字母的东西。
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
。
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所述。
相关文章:
- 将用户定义的类型与 std::vector 和 std::sort 一起使用
- 你能在 c++ 中将不同的数字类型加在一起吗?
- 将 unordered_map 与 Catch2 谓词一起使用时类型不匹配
- 如何将result_of与函数类型定义一起使用
- 将 lower_bound/upper_bound 与 2 种不同的类型一起使用
- 不允许将SDL_Cursor与unique_ptr:error不完整类型一起使用
- 将-Wtype限制与类型泛型代码一起使用
- 将提升属性映射与捆绑类型一起使用
- 将运算符<<与隐式转换的非基本数据类型一起使用时出错
- 如何将两个 jlong 数据类型转换为 jstring,然后将两个字符串连接在一起以便从 JNI 将字符串返回给 jav
- 将分配的内存与基本数据类型一起使用时,是否需要新放置? std::complex?
- (如何)在提升几何中创建自己的多边形类型并与之一起使用multi_polygon类型?
- 是否可以将引用类型别名与指针运算符一起使用来声明对指针的引用?
- 如何将模运算符与其他数据类型一起使用
- 将 PIMPL 习惯用法与成员函数模板一起使用(无需预先了解所有可能的数据类型)
- 重值引用不是将类型和类别混合在一起吗?
- 与 2 个相关类一起无效使用不完整类型
- 使用#Define和Typedef与数据类型A一起使用
- 如何编写操作员==与隐式铸造/构造类型一起使用
- 将类型名与 reinterpret_cast() 一起使用