C ++:是否可以创建返回null的模板函数?

时间:2016-01-08 13:13:39

标签: c++ templates

我有一个可以返回不同类型的模板函数。

template <class typ>
typ GetRespVal_byField(const std::string & _fname){
for (pqxx::result::const_iterator row = m_result.begin();
     row != m_result.end();
     ++row)
    {
        if (!row[_fname].is_null())
            return row[_fname].as<typ>();
        else
            return NULL; //this is what i want 

    }
}

这是正确的实施吗?

5 个答案:

答案 0 :(得分:3)

至于typ可以获取NULL值(或者如果typ对象可以从NULL值构建),是的,您可以。如果type是指针或例如int

您甚至可以返回foo_bar ....如果foo_bar是有效的typ值,它就会有效....

模板解析是在编译时完成的,因此,正如YSC所评论的,如果它编译,那么是的,它在类型检查方面是允许的(现在,代码编译并不一定意味着它将在运行时,但是,对于您的具体问题,它已经足够好了...... ....

答案 1 :(得分:2)

  

是否可以创建返回null的模板函数?

一般来说,是的,当然。模板功能为什么不能这样做?

...然而

  

这是正确的实施吗?

这取决于你对“正确”的定义:)

例如,如果您尝试使用std::stringtyp实例化该函数,则返回NULL将调用未定义的行为(因为您将尝试从std::string构建NULL一个空指针)。未定义的行为通常被认为是非常不正确的行为。

Boost.Optional视为表示某事物不存在的替代方法。它比checkDoc更通用。

答案 2 :(得分:2)

这是可能的,但可能并不总是一个好主意。例如,如果typstring,那么您的代码将被编译,因为NULL将被解释为char *,从中隐式构造一个字符串。但是,当else分支被命中时,代码将在运行时失败,因为尝试从NULL构造字符串是未定义的行为,几乎肯定会导致访问冲突。

因此,我建议至少对您的代码进行两项改进。

  1. 将类型特征与static_assert结合使用,以确保typ是指针类型。将其添加到模板函数中:

    static_assert(is_pointer<typ>::value, "<typ> must be a pointer type");
    

    这排除了不是指针的类型,但可以从指针构造,并且还使用户更清楚地显示错误消息。

  2. 返回nullptr而不是NULL - 主要是为了使意图更明确,但也要避免在转换为整数类型时会出现问题的假设情况(与{{1不同) },NULL不会隐式转换为整数类型。)

答案 3 :(得分:1)

更一般地说,编译模板并没有太大作用。微软最近才abandoned something可以大致调用模板的文本替换实现:

  

在旧编译器中选择实现此[模板]的方法是进行一些最小的解析   一个模板,然后将整个模板捕获为一串标记   (这与编译器中处理宏的方式非常相似)。 稍后,当实例化模板时,将通过解析器重放该令牌流,并且将替换模板参数。

放弃这个原因的原因是正确实现模板还不够。但是C ++中的模板仍然是语义上的模板,这就是为什么使用代码编译模板的常用方法涉及使模板源可用。

这与C#形成鲜明对比,C#严格意义上编译独立模板(当然是IL)。

实例化模板可以做更多事情:

#include<iostream>

using namespace std;

// this works;
template<typename T> T f(T t)
{
    return cout;
}       

// this doesn't 
// double  d = f(1.0);

答案 4 :(得分:0)

您可以编写一个类型特征类,它将为您使用的任何类型定义NULL。我想你会遇到问题 - 你会为deviceName指定什么NULL?您可以更改功能签名并返回std::string其中:

  1. 如果返回非NULL值,则std::pair<typ, bool>等于返回值,first等于second
  2. 如果应返回NULL值,则首先等于默认初始化typ,truesecond