如何插入变量类型作为参数函数?

时间:2016-02-10 12:15:07

标签: c++ function parameters

我有以下功能:

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;
}
  1. 如何创建一个包含checktype类型的变量(是否可能)?

  2. 为每种可能的checktype值创建通用的readAndCheck函数有什么方法?

  3. 我问这个,因为为每个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;
    }
    

1 个答案:

答案 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";
        }
    }
}

否则所有关于学习模板的文档都应该帮助你; - )