Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 默认值的函数模板_C++ - Fatal编程技术网

C++ 默认值的函数模板

C++ 默认值的函数模板,c++,C++,我这里有一些代码,它使用特殊值检查变量是否初始化 #define NULLVALUE_FLOAT -9999 #define NULLVALUE_INT -9999 #define NULLVALUE_UINT 0 #define NULLVALUE_DOUBLE -9999 #define NULLVALUE_LONG -9999 #define NULLVALUE_LONGLONG -9999 #

我这里有一些代码,它使用特殊值检查变量是否初始化

#define NULLVALUE_FLOAT         -9999
#define NULLVALUE_INT           -9999
#define NULLVALUE_UINT          0
#define NULLVALUE_DOUBLE        -9999
#define NULLVALUE_LONG          -9999
#define NULLVALUE_LONGLONG      -9999
#define NULLVALUE_CSTRING       ""

bool isNull(float value) { return NULLVALUE_FLOAT == value; }
bool isNull(double value); ...
bool isNull(long value);...
bool isNull(int value);...
bool isNull(UINT value);...
bool isNull(CString value);...
所以unsigned的特殊值是零,signed int和floating point是-9999,string是空字符串

现在我想把它重写成一个模板函数,但是由于CString版本的原因,它有问题。我能做的最好的是两个函数,一个用于基本类型,另一个用于CString

template<typename T,
    bool E = std::is_fundamental<T>::value && !std::is_unsigned<T>::value && (std::is_floating_point<T>::value || std::is_integral<T>::value),
    bool E2 = std::is_fundamental<T>::value && std::is_unsigned<T>::value>
bool isNull(const T &t) 
{ 
    if (E)
        return t == -9999;
    else if (E2)
        return t == 0;
    else
        return false;
}

bool isNull(const CString &  s)
{
    return s == "";
}
模板
布尔值为空(常数T&T)
{ 
如果(E)
返回t==-9999;
如果有的话(E2)
返回t==0;
其他的
返回false;
}
布尔值为空(常数CString&s)
{
返回s==“”;
}

即使在添加具有默认值的其他类时,是否可以仅使用一个函数来实现此功能?

如果您将重点从定义函数转移到定义命名空值的方法,那么解决方案将非常容易地呈现出来

添加一个traits类,该类公开
成员。只要你觉得方便,就把它专门化

template<typename T, typename = void>
struct NullValueHolder{};

template<typename T>
constexpr decltype(NullValueHolder<T>::value) NullValue = NullValueHolder<T>::value;  
// Utility for easy referral 

template<typename T>
struct NullValueHolder<T, std::enable_if_t<std::is_arithmetic<T>::value && std::is_signed<T>::value>> {
  static constexpr T value = -9999;
};

template<typename T>
struct NullValueHolder<T, std::enable_if_t<std::is_unsigned<T>::value>> {
  static constexpr T value = 0;
};

template<>
struct NullValueHolder<CString, void> {
  static constexpr const char * value = "";
};

如果您将注意力从定义函数转移到定义命名空值的方法上,那么解决方案将很容易出现

添加一个traits类,该类公开
成员。只要你觉得方便,就把它专门化

template<typename T, typename = void>
struct NullValueHolder{};

template<typename T>
constexpr decltype(NullValueHolder<T>::value) NullValue = NullValueHolder<T>::value;  
// Utility for easy referral 

template<typename T>
struct NullValueHolder<T, std::enable_if_t<std::is_arithmetic<T>::value && std::is_signed<T>::value>> {
  static constexpr T value = -9999;
};

template<typename T>
struct NullValueHolder<T, std::enable_if_t<std::is_unsigned<T>::value>> {
  static constexpr T value = 0;
};

template<>
struct NullValueHolder<CString, void> {
  static constexpr const char * value = "";
};

现在C++17已经用于VisualStudio,使用其“if constexpr”功能可以很容易地解决这个问题。让编译器根据需要生成函数

template<typename T>
bool isDefault(const T &t)
{
    if constexpr (std::is_unsigned<T>::value)
    {
        return t == 0;
    }
    else if constexpr (std::is_floating_point<T>::value || std::is_integral<T>::value)
    {
        return t == -9999;
    }
    else if constexpr (std::is_same<T, CString>::value)
    {
        return t == "";
    }
    else if constexpr (std::is_same<T, COleDateTime>::value)
    {
        return t.GetStatus() == COleDateTime::null;
    }
}
模板
布尔isDefault(常数T&T)
{
如果constexpr(std::is_unsigned::value)
{
返回t==0;
}
如果constexpr(std::is_floating_point::value | | std::is_integral::value)
{
返回t==-9999;
}
否则如果constexpr(std::is_same::value)
{
返回t==“”;
}
否则如果constexpr(std::is_same::value)
{
返回t.GetStatus()==COleDateTime::null;
}
}

现在C++17已经在visual studio中推出,这可以通过其“if constexpr”功能轻松解决。让编译器根据需要生成函数

template<typename T>
bool isDefault(const T &t)
{
    if constexpr (std::is_unsigned<T>::value)
    {
        return t == 0;
    }
    else if constexpr (std::is_floating_point<T>::value || std::is_integral<T>::value)
    {
        return t == -9999;
    }
    else if constexpr (std::is_same<T, CString>::value)
    {
        return t == "";
    }
    else if constexpr (std::is_same<T, COleDateTime>::value)
    {
        return t.GetStatus() == COleDateTime::null;
    }
}
模板
布尔isDefault(常数T&T)
{
如果constexpr(std::is_unsigned::value)
{
返回t==0;
}
如果constexpr(std::is_floating_point::value | | std::is_integral::value)
{
返回t==-9999;
}
否则如果constexpr(std::is_same::value)
{
返回t==“”;
}
否则如果constexpr(std::is_same::value)
{
返回t.GetStatus()==COleDateTime::null;
}
}

您拥有的已经非常少了。如果您尝试过,可以在C++17中使用
constexpr if
将其折叠成一个。此外,如果您只是想显式地在函数中写入文本,为什么还要麻烦使用难看的宏?@Rakete1111-您链接的问题会使它成为一个副本吗?模板函数专门化几乎不能解决任何问题。@StoryTeller我猜,但这个问题要求根据模板类型计算不同表达式的方法,所以我认为它是重复的。@Rakete1111-我读这个问题是问如何使它成为一个单一的函数,没有重载或专门化函数。您拥有的已经非常少了。如果您尝试过,可以在C++17中使用
constexpr if
将其折叠成一个。此外,如果您只是想显式地在函数中写入文本,为什么还要麻烦使用难看的宏?@Rakete1111-您链接的问题会使它成为一个副本吗?模板函数专门化几乎不能解决任何问题。@StoryTeller我猜,但这个问题要求根据模板类型计算不同表达式的方法,所以我认为它是重复的。@Rakete1111-我读这个问题是问如何使它成为一个单一的函数,无需重载或专门化函数。