std :: string与模板一起使用,检查是否为空

时间:2016-03-28 19:19:28

标签: c++

我想使用一个接受T类型的通用参数的函数,并在函数内检查传入的变量是否为NULL。我可以简单地用这样的原始类型做到这一点:

if (var) doSomething();

但是,为了检查它是否为std::string,我需要这样做:

if (!var.empty()) doSomething();

检查传入的参数是NULL的最佳,最常用的方法是什么?我想使用所有原始类型和std::string。也许我可以使用typeid

2 个答案:

答案 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

live demo

您唯一的另一个选择是接受指向对象的指针并检查指针上的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