我有以下功能:
int readAndCheck () {
int n;
while (n < 2) {
try {
cout << "Please insert an integer bigger than one: ";
string check = "";
cin >> check;
n = boost::lexical_cast<int>(check);
} catch (boost::bad_lexical_cast&) {
cout << "Error!\n";
}
}
return n;
}
我想概括一下这个函数,以便它可以向用户输出任何请求并检查任何类型。但我知道以下是不可能的:
checktype readAndCheck (string request, checktype) {
checktype n;
while (n < 2) {
try {
cout << request;
string check = "";
cin >> check;
n = boost::lexical_cast<checktype>(check);
} catch (boost::bad_lexical_cast&) {
cout << "Error!\n";
}
}
return n;
}
如何创建一个包含checktype类型的变量(是否可能)?
为每种可能的checktype值创建通用的readAndCheck函数有什么方法?
我问这个,因为为每个checktype创建一个函数似乎很乏味。
解:
#include <iostream>
#include <boost/lexical_cast.hpp>
template<typename CheckType>
CheckType readAndCheck(std::string request, CheckType n)
{
try {
std::cout << request;
std::string check = "";
std::cin >> check;
n = boost::lexical_cast<CheckType>(check);
} catch (boost::bad_lexical_cast&) {
std::cout << "Error!\n";
}
return n;
}
int main()
{
int a = 0;
while (a < 2)
a = readAndCheck("Please insert a integer bigger than one: ", a);
std::cout << a << "\n";
return 0;
}
答案 0 :(得分:2)
C ++的几个支柱之一是一个名为template
的功能,其存在的主要原因之一就是缓解这种情况,否则将需要非常重复的代码。< / p>
文档非常丰富,但简而言之,您的想法是声明一个template
d类或函数,使用泛型类型或整数(包括指针)模板参数作为占位符真实的类型或价值观。在您使用所有必需参数实例化此模板之前,template
不是类型,从中创建实际类型/代码。
通过类的声明(例如 template
)或函数,声明或调用(例如)实例化MyTemplate<Arguments> myInstance{ctor_args}
myFunc<OptionalArguments>(func_args)
;另见下文)。您在实例化期间提供的参数将替换为前面指定的占位符(在远比宏更复杂的方式!),最后创建一个具体的模板类(和相关代码)或函数,其中包含或行为根据指定的类型/积分值。
对于更复杂的情况,模板可以显式专用,对不同的模板参数集采取不同的行动。也就是说,您可以指定一个处理大多数类型的通用模板,但如果需要其他代码,则显式专门用于给定的参数集。
模板函数通常不需要您显式指定模板参数,如果可以从调用站点明确地推断出这些参数(即由函数类型参数)。如果无法推断模板参数(例如。没有相应的函数参数),那么在调用时必须提供它们,就像在实例化模板类时一样<Brackets>
。
我现在无法测试代码(我也不知道boost::lexical_cast
如何工作),但你的简单案例就是 这样:
// Return a new instance - can't deduce type, must specify at call site
// Call like: auto checked{ readAndCheck<YourType>(yourRequest) };
template<typename T_CheckType>
T_CheckType readAndCheck(std::string request)
{
// assumes T_CheckType not initialised with gibberish:
T_CheckType n;
while (n < 2) { // assumes T_CheckType convertible to int
try {
std::cout << request;
std::string check = "";
std::cin >> check;
n = boost::lexical_cast<T_CheckType>(check);
} catch (boost::bad_lexical_cast&) {
std::cout << "Error!\n"; // may return invalid instance
}
}
return n;
}
// XOR
// Write result to passed output parameter - enables deduction from arg #2
// Call like: readAndCheck(yourRequest, yourOutputParameter);
template<typename T_CheckType>
void readAndCheck(std::string request, T_CheckType &output_checked)
{
// reinitialise output_checked here if required
while (output_checked < 2) { // assumes T_CheckType convertible to int
try {
std::cout << request;
std::string check = "";
std::cin >> check;
output_checked = boost::lexical_cast<T_CheckType>(check);
} catch (boost::bad_lexical_cast&) {
std::cout << "Error!\n";
}
}
}
否则所有关于学习模板的文档都应该帮助你; - )