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

C++ C++;:是否可以创建返回null的模板函数?,c++,templates,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())

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

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 

    }
}
模板
类型GetRespVal_byField(常量标准::字符串和名称){
for(pqxx::result::const_迭代器行=m_result.begin();
行!=m_result.end();
++(世界其他地区)
{
如果(!row[\u fname]。为\u null())
返回行[_fname].as();
其他的
return NULL;//这就是我想要的
}
}

这是一个正确的实现吗

只要
typ
可以接受
NULL
值(或者如果
typ
对象可以从
NULL
值构造),是的,您可以。例如,如果
type
是指针或
int

您甚至可以返回
foo\u bar
…如果
foo\u bar
是一个有效的
typ
值,它将工作


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

只要
typ
可以接受
NULL
值(或者如果
typ
对象可以由
NULL
值构造),则可以。例如,如果
type
是指针或
int

您甚至可以返回
foo\u bar
…如果
foo\u bar
是一个有效的
typ
值,它将工作

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

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

一般来说,是的,当然。为什么模板函数不能做到这一点

然而

这是一个正确的实现吗

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

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

考虑作为一种替代来表示某事物的不存在。它比
NULL
更通用

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

一般来说,是的,当然。为什么模板函数不能做到这一点

然而

这是一个正确的实现吗

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

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


考虑作为一种替代来表示某事物的不存在。它比
NULL

更通用。更一般地说,编译模板并没有什么用处。Microsoft最近才大致称为模板的文本替换实现:

选择的实现这个[旧编译器中的模板]的方法是对 一个模板,然后将整个模板捕获为一个令牌字符串 (这与编译器中处理宏的方式非常相似)稍后,当模板被实例化时,该令牌流将通过解析器重放,模板参数将被替换

之所以放弃这种方法,是因为它不足以正确地实现模板。但是C++中的模板仍然是语义上的模板,这就是为什么使用代码编译模板的常用方法包括模板源的可用性。p> 这与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);
#包括
使用名称空间std;
//这是有效的;
模板tf(T)
{
返回cout;
}       
//这并不重要
//双d=f(1.0);

更一般地说,编译模板没什么用处。Microsoft最近才大致称为模板的文本替换实现:

选择的实现这个[旧编译器中的模板]的方法是对 一个模板,然后将整个模板捕获为一个令牌字符串 (这与编译器中处理宏的方式非常相似)稍后,当模板被实例化时,该令牌流将通过解析器重放,模板参数将被替换

之所以放弃这种方法,是因为它不足以正确地实现模板。但是C++中的模板仍然是语义上的模板,这就是为什么使用代码编译模板的常用方法包括模板源的可用性。p> 这与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);
#包括
使用名称空间std;
//这是有效的;
模板tf(T)
{
返回cout;
}       
//这并不重要
//双d=f(1.0);

您可以编写一个类型特征类,该类将为您使用的任何类型定义空值。我想您可能会有问题-您会为
std::string
指定什么空值?您可以更改函数签名并返回
std::pair
其中:

  • 如果返回非空值,则
    第一个
    等于返回的值,而
    第二个
    等于
  • 若应返回NULL值,则第一个为