2015-06-08 119 views
0

在当前状态下,程序验证数据类型的输入:int和string。函数模板重载(不同数据类型验证函数作为参数)

//valid score range between 0 and 100 
bool validScore(int value) 
{ 
    if(value < 0 || value > 100) 
     return false; 
    return true; 
} 
//valid name composed of letters 
bool validName(string word) 
{ 
    for(int i = 0; i < word.length(); i++) 
    { 
    if(!isalpha(word[i])) 
     return false; 
    } 
    return true; 
} 

输入是通过两种函数为每种数据类型获取的:get_int()和get_word()。

对于int范围未指定且名称可能包含任何字符的情况,验证函数是可选参数。

bool get_int(const string&, int&, bool(*validScore)(int) = 0); 
bool get_word(const string&, string&, bool(*validWord)(const string) = 0); 

// bool get_int(const string& prompt, int&n, (*validScore)(int)) 
bool get_word(const string& prompt, string&word, bool(*validWord)(const string)) 
{ 
    while(1) 
    { 
    string line; 
    cout << prompt; 

    if(!getline(cin, line) 
     break; 

    istringstream iss(line); 

    if(iss >> word) // iss >> n 
    { 
     // validScore == 0 || validScore(n) 
     if(validWord == 0 || validWord(word)) 
     return true; 
    } 
    } 
    return false; 
} 

我在想,如果可能的话,如何正确声明一个函数模板,可以简化流程时需要验证。

template<typename T> bool get_item(const string&, T&, ???); 

将函数模板get_item重载与不同的验证函数是一个潜在的解决方案吗?

+0

好像你只是想要一个模板函数'valid(const T&)',它只支持它所支持的类型的专门化? – dwcanillas

回答

3

如果你很喜欢函数指针,然后

template<typename T> bool get_item(const string&, T&, bool (*)(const T&) = nullptr); 

template<typename T> bool get_item(const string&, T&, bool (*)(T) = nullptr); 

,以匹配您的valid*功能存在的签名(注意,这会招致复印件)。

你也可以把它完全通用:

template<typename T, typename F> bool get_item(const string&, T&, F); 

来处理情况,不需要验证的情况下,单独的过载,可以用:

template<typename T> bool get_item(const string &s, T &t){ 
    return get_item(s, t, [](const T&){return true;}); 
} 
+0

你应该改为“如果你真的喜欢函数指针语法。”通用版本仍然使用函数指针(如果通过的话)。在没有传递函数指针的情况下,原始版本也不起作用(除了函子提供相应转换操作符的小部分情况外)。 – Columbo

+0

我有时使用'[](T const&) - > std :: true_type {return {};}'作为额外的提示给优化器。不知道它有什么不同。 – Yakk

0

以验证作为模板类型:

template<class T> 
bool get_item(const string& prompt, T& item); 

template<class T, class Validator> 
bool get_item(const string& prompt, T& item, Validator validator); 

这里有一个隐含的模板策略,可以调用Validator用T并返回一个布尔值。由于C++还没有的概念,你可以评论模板策略。

相关问题