我有一个可以返回不同类型的模板函数。
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
}
}
这是正确的实施吗?
答案 0 :(得分:3)
至于typ
可以获取NULL
值(或者如果typ
对象可以从NULL
值构建),是的,您可以。如果type
是指针或例如int
。
您甚至可以返回foo_bar
....如果foo_bar
是有效的typ
值,它就会有效....
模板解析是在编译时完成的,因此,正如YSC所评论的,如果它编译,那么是的,它在类型检查方面是允许的(现在,代码编译并不一定意味着它将在运行时,但是,对于您的具体问题,它已经足够好了...... ....
答案 1 :(得分:2)
是否可以创建返回null的模板函数?
一般来说,是的,当然。模板功能为什么不能这样做?
...然而
这是正确的实施吗?
这取决于你对“正确”的定义:)
例如,如果您尝试使用std::string
为typ
实例化该函数,则返回NULL
将调用未定义的行为(因为您将尝试从std::string
构建NULL
一个空指针)。未定义的行为通常被认为是非常不正确的行为。
将Boost.Optional视为表示某事物不存在的替代方法。它比checkDoc
更通用。
答案 2 :(得分:2)
这是可能的,但可能并不总是一个好主意。例如,如果typ
是string
,那么您的代码将被编译,因为NULL将被解释为char *
,从中隐式构造一个字符串。但是,当else
分支被命中时,代码将在运行时失败,因为尝试从NULL构造字符串是未定义的行为,几乎肯定会导致访问冲突。
因此,我建议至少对您的代码进行两项改进。
将类型特征与static_assert
结合使用,以确保typ
是指针类型。将其添加到模板函数中:
static_assert(is_pointer<typ>::value, "<typ> must be a pointer type");
这排除了不是指针的类型,但可以从指针构造,并且还使用户更清楚地显示错误消息。
返回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
其中:
std::pair<typ, bool>
等于返回值,first
等于second
。 true
为second