我想使用一个接受T
类型的通用参数的函数,并在函数内检查传入的变量是否为NULL
。我可以简单地用这样的原始类型做到这一点:
if (var) doSomething();
但是,为了检查它是否为std::string
,我需要这样做:
if (!var.empty()) doSomething();
检查传入的参数是NULL
的最佳,最常用的方法是什么?我想使用所有原始类型和std::string
。也许我可以使用typeid
?
答案 0 :(得分:6)
首先,如果您使用了适当的术语,那么您可以更好地研究这个主题。空字符串不是" NULL
&#34 ;;零等价整数也不是" NULL
"。唯一可能是" NULL
"是一个指针(尽管我们现在使用nullptr
)。所以我们马上就可以停止使用这个术语了。
没有一般&#34;没有设置&#34;任意类型的值,因此没有常见的方法来检测这种情况。但是,您可以使用明确添加此可能性的包装类型,例如boost::optional<T>
:
#include <boost/optional.hpp>
#include <iostream>
template <typename T>
void foo(boost::optional<T> arg)
{
if (arg)
std::cout << arg.get() << '\n';
}
int main()
{
boost::optional<int> a{123};
boost::optional<int> b{boost::none};
boost::optional<float> c{boost::none};
boost::optional<float> d{123.456};
foo(a);
foo(b);
foo(c);
foo(d);
// Or, pass it directly:
foo(boost::optional<std::string>{"abc"});
foo(boost::optional<std::string>{boost::none});
foo(boost::optional<std::string>{}); // as if boost::none were given
}
// $ g++ -std=c++14 -O2 -Wall -Wextra -pedantic -pthread main.cpp && ./a.out
// 123
// 123.456
// abc
您唯一的另一个选择是接受指向对象的指针并检查指针上的NULL
度。但这是一个抽象泄漏,因为接受指针表示除了此函数之外的其他意图;它还会在明确所有权语义方面造成一些混乱。
答案 1 :(得分:0)
您可以使用通用代码,而不必重复使用与该对象的默认构造版本进行比较的模板:
#include <iostream>
#include <string>
template <typename T>
void doSomething(T t)
{
std::cout << "Doing something with " << t << " \n";
}
void doSomethingElse()
{
std::cout << "Doing something else\n";
}
template <typename T>
void f(T t)
{
if (t!=T{}) doSomething(t); // compare with default constructed object
else doSomethingElse();
}
int main()
{
int var1{};
std::string var2{};
int var3{3};
std::string var4{"var4's text"};
f(var1);
f(var2);
f(var3);
f(var4);
}
产地:
Doing something else
Doing something else
Doing something with 3
Doing something with var4's text