使用模板理解 constexpr 函数 [C++]
Understanding constexpr functions with templates [C++]
我正在尝试了解 C++ 中的 constexpr 函数。我无法理解第一个函数定义有什么问题。我认为所有的变量都应该在编译时可用。
我正在使用 Catch2 作为测试库。
sqrtfunc.hpp
#include <stdexcept>
#include <numeric>
template <class T>
constexpr T max_iterations = std::numeric_limits<T>::max_exponent();
template <class T>
constexpr T epsilon = std::numeric_limits<T>::epsilon();
// This function definition doesn't work
template <class T>
constexpr T sqrtFunc(T x){
if(x < 0){
throw std::domain_error("Argument must be >= 0");
}
else if(x == 0){
return x;
}
const T c = x;
T xn = x;
size_t i = 0;
while (i < max_iterations<T>){
T xnplus_1 = xn - (sqr(xn) - c) / ( 2 * xn);
if (abs(xnplus_1 - xn) <= epsilon<T>){
break;
}
xn = xnplus_1;
i++;
}
return xn;
}
// This function definition works
template <class T>
constexpr T sqrtFunc(T x){
if(x < 0){
throw std::domain_error("Argument must be >= 0");
}
else if(x == 0){
return x;
}
const T c = x;
T xn = x;
// size_t i = 0;
while (true){
T xnplus_1 = xn - (sqr(xn) - c) / ( 2 * xn);
if (abs(xnplus_1 - xn) <= epsilon<T>){
break;
}
xn = xnplus_1;
// i++;
}
return xn;
}
test_file.cpp
TEST_CASE("SQRT"){
SECTION("Square root"){
constexpr double var = 4.0;
REQUIRE(sqrtFunc(var) == Approx(2.0).margin(0.0001));
}
}
第一个函数声明的错误如下:
error C2064: term does not evaluate to a function taking 0 arguments
note: see reference to variable template 'const T max_iterations<double>' being compiled
[
T=double
]
note: see reference to function template instantiation 'T sqrtFunc<double>(T)' being compiled
[
T=double
]
对于具有第二个声明的完全相同的 cpp 文件,我得到了正确的输出。
如果有帮助,我正在使用 Visual Studio 2017。C/C++ Optimizing Compiler Version 19.16.27045 for x86
注意:我已经进行了所有必要的导入 (#include
)。
您正在调用 std::numeric_limits<T>::max_exponent
,但它是一个变量,而不是一个函数。
我正在尝试了解 C++ 中的 constexpr 函数。我无法理解第一个函数定义有什么问题。我认为所有的变量都应该在编译时可用。
我正在使用 Catch2 作为测试库。
sqrtfunc.hpp
#include <stdexcept>
#include <numeric>
template <class T>
constexpr T max_iterations = std::numeric_limits<T>::max_exponent();
template <class T>
constexpr T epsilon = std::numeric_limits<T>::epsilon();
// This function definition doesn't work
template <class T>
constexpr T sqrtFunc(T x){
if(x < 0){
throw std::domain_error("Argument must be >= 0");
}
else if(x == 0){
return x;
}
const T c = x;
T xn = x;
size_t i = 0;
while (i < max_iterations<T>){
T xnplus_1 = xn - (sqr(xn) - c) / ( 2 * xn);
if (abs(xnplus_1 - xn) <= epsilon<T>){
break;
}
xn = xnplus_1;
i++;
}
return xn;
}
// This function definition works
template <class T>
constexpr T sqrtFunc(T x){
if(x < 0){
throw std::domain_error("Argument must be >= 0");
}
else if(x == 0){
return x;
}
const T c = x;
T xn = x;
// size_t i = 0;
while (true){
T xnplus_1 = xn - (sqr(xn) - c) / ( 2 * xn);
if (abs(xnplus_1 - xn) <= epsilon<T>){
break;
}
xn = xnplus_1;
// i++;
}
return xn;
}
test_file.cpp
TEST_CASE("SQRT"){
SECTION("Square root"){
constexpr double var = 4.0;
REQUIRE(sqrtFunc(var) == Approx(2.0).margin(0.0001));
}
}
第一个函数声明的错误如下:
error C2064: term does not evaluate to a function taking 0 arguments
note: see reference to variable template 'const T max_iterations<double>' being compiled
[
T=double
]
note: see reference to function template instantiation 'T sqrtFunc<double>(T)' being compiled
[
T=double
]
对于具有第二个声明的完全相同的 cpp 文件,我得到了正确的输出。
如果有帮助,我正在使用 Visual Studio 2017。C/C++ Optimizing Compiler Version 19.16.27045 for x86
注意:我已经进行了所有必要的导入 (#include
)。
您正在调用 std::numeric_limits<T>::max_exponent
,但它是一个变量,而不是一个函数。