【发布时间】:2016-06-28 06:54:59
【问题描述】:
我写了以下代码:
#include<array>
#include<type_traits>
namespace math{
namespace detail{
template<std::size_t... Is> struct seq{};
template<std::size_t N, std::size_t... Is>
struct gen_seq : gen_seq<N-1, N-1, Is...>{};
template<std::size_t... Is>
struct gen_seq<0, Is...> : seq<Is...>{};
template<class T,std::size_t N>
struct sin_coeffs{
using array_type = std::array<T,N>;
constexpr static inline T coeff(std::size_t n){
return power(-1, n-1) * inverse((T)factorial((2 * n)-1));
}
template<std::size_t...NS>
constexpr static array_type _coeffs(seq<NS...>){
return {{coeff(NS)...}};
}
constexpr static array_type coeffs=_coeffs(gen_seq<N>{});
};
}
template<class T,std::size_t N = max_factorial, class dcy = std::decay_t<T>>
constexpr std::enable_if_t<std::is_floating_point<dcy>::value,dcy> sin(T x) noexcept{
constexpr std::array<dcy,N>& coeffs = detail::sin_coeffs<dcy,N>::coeffs;
const dcy x_2 = x*x;
dcy pow = x;
dcy result = 0;
for(std::size_t i=0;i<N;++i){
result += coeffs[i] * pow;
pow*=x_2;
}
return result;
}
}
示例主要:
int main()
{
constexpr double d = math::sin(0.0);
}
代码被设计成一个 constexpr sin 函数,它使用一个 constexpr 数组来保存系数来进行所需的计算。
所有未列出的函数都出现在单独的头文件中,并且编译没有问题。
我正在尝试使用“indicies”技巧来使用基于this answer to another question 的 constexpr 函数填充数组。
我正在使用带有标志的 GCC 5.3.1 进行编译
--std=c++1z -pthread -g -O3 -MMD -MP -Wall -pedantic
编译器不会向我的代码发出错误,但在编译时会停止。
我让编译运行了几分钟,但它什么也没做。
我已经测试了代码中使用的所有函数,它们都可以独立于本节编译。
int main()
{
math::detail::sin_coeffs<double,20>::coeffs[0];
}
这段代码 sn-p 也重现了这个问题,这让我相信它与 sin 函数本身无关,而是与 sin_coeffs 结构有关。
编辑: 以下是要求的其他功能:
#include <type_traits>
namespace math{
template<class T,class dcy = std::decay_t<T>>
constexpr inline std::enable_if_t<std::is_floating_point<T>::value,dcy> inverse(T value){
return (value == 0) ? 0.0 : 1.0 / value;
}
template <class T>
constexpr inline std::decay_t<T> sign(T value) {
return value < 0 ? -1 : 1;
}
template <typename T>
constexpr inline std::decay_t<T> abs(T value) {
return value * sign(value);
}
template<class T>
constexpr inline std::decay_t<T> power(T const& base, std::size_t const& pow){
if(pow==0){return 1;}
else if(pow == 1){return base;}
else{
T result = base;
for(std::size_t i=1;i<pow;++i){
result*=base;
}
return result;
}
}
constexpr std::intmax_t factorial(std::intmax_t const& n){
if(n==0){return 1;}
std::intmax_t result = n;
for(std::intmax_t i=n-1;i>0;--i){
result *=i;
}
return result;
}
constexpr static std::size_t max_factorial = 20;//replace with calculated version later
}
【问题讨论】:
-
能否至少提供缺失函数的声明(无主体)以便我们编译?
-
要回显@Holt,没有
power等,您显示的代码没有 有用。见sscce.org。 -
我不是 100% 确定,但由于
gen_seq的终止条件是N = 0,您的序列中可能有一个0,因此您将调用coeff(0)将在我的架构上调用power(-1, ((size_t)0) - 1),即power(-1, 18446744073709551615),这显然永远不会编译。 -
@AlexZywicki 请参阅我的(现已编辑)答案,了解有关为什么您的代码未编译以及如何修复所有问题的指示。
标签: c++ gcc c++14 variadic-templates