gpt4 book ai didi

c++ - 'if' 带有模板参数或 SFINAE 是首选?

转载 作者:IT老高 更新时间:2023-10-28 21:36:03 26 4
gpt4 key购买 nike

首选是这样的:

template<typename T>
bool isNotZero(const T &a)
{
if (std::is_floating_point<T>::value) return abs(a) > std::numeric_limits<T>::epsilon();
else return a;
}

或者这个:?

template<typename T>
std::enable_if<std::is_floating_point<T>::value, bool>::type
isNotZero(const T &a) { return abs(a) > std::numeric_limits<T>::epsilon(); }

template<typename T>
std::enable_if<std::is_integral<T>::value, bool>::type
isNotZero(const T &a) { return a; }

我通常使用第一种来避免许多版本的功能。

我相信是完全一样的。

第一个版本在操作码阶段优化,第二个版本在模板实例化阶段。

最佳答案

I believe it is exactly the same.

我不会说它一模一样

在第一个版本中,您使用的条件语句在运行时评估,但是决定执行哪个分支的条件可以(并且是)在 编译时

因此,无论输入的类型是什么,您的两个分支都必须编译并且将被编译,即使我们在编译时知道其中只有一个会被执行而另一个会死 - 我希望编译器会在这里发出警告。

在第二种情况下,您只需编译(当然是执行)适合输入类型的内容。在我看来,这使得第二种方法更胜一筹。

现在,即使在这种特殊情况下,您选择哪种方法可能没有区别,由编译时条件决定的条件执行应该通过编译时构造来表示 - SFINAE 和模板重载,而 if 应用于取决于系统运行时状态的条件。

第一种方法是不可能的,例如,如果条件的两个分支包含仅在执行相应分支时编译的代码。考虑这两种类型:

struct X
{
X(int) { }
};

struct Y
{
Y() { }
};

还有如下函数模板:

template<typename T>
T foo(const T &a)
{
if (std::is_constructible<T, int>::value)
{
return T(42);
}
else
{
return T();
}
}

现在以下调用都不合法:

foo(X()); // ERROR! X is not default-constructible
foo(Y()); // ERROR! Y is not constructible from an int

仅此一点就表明,处理编译时条件执行的适当工具通常是模板重载 + SFINAE(或可能涉及类模板特化的等效构造)。

当然,有退化案例(例如这个)允许您使用其他工具,但如果我们正在寻找概念上正确的设计指南,我相信这里有一个明显的赢家。

如果像 static if 这样的话,情况当然会有所不同。存在于 C++ 中,但目前情况并非如此 - 似乎在不久的将来也不会。

关于c++ - 'if' 带有模板参数或 SFINAE 是首选?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16178756/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com