constexpr如果太复杂(错误c1202) [英] constexpr if too complicated (error c1202)
问题描述
您好,我知道这是一个有点愚蠢的问题,但我想用visual studio编译器报告一些可能奇怪的行为。
Hello, I know this is a bit of a silly problem, but I wanted to report some potentially weird behavior with the visual studio compiler.
我写了这段代码
template<uint64_t val, uint64_t counter = 0>
constexpr uint64_t CollatzChainLength()
{
if constexpr (val == 1)
{
return counter;
}
if constexpr (val % 2 == 0)
{
return CollatzChainLength<val / 2, counter + 1>();
}
else
{
return CollatzChainLength<val * 3 + 1, counter + 1>();
}
}
当我尝试调用CollatzChainLength< 4,0>()时,我收到了c1202错误。但是,如果我删除计数器作为模板参数(是CollatzChainLength< val * 3 + 1,counter>(),现在是CollatzChainLength< val * 3>()),它编译精细
(即使它没有实际上解决了我想要的问题。我已经为这类问题编写了类似的代码(见下文)并编译得很好。
and I got the c1202 error when I tried to call CollatzChainLength<4, 0>(). However, if I remove counter as a template argument to (was CollatzChainLength<val * 3 + 1, counter>(), now is CollatzChainLength<val * 3>()), it compiles fine (even though its doesn't actually solve the problem i want it too). I've written similar code to this kind for this kind of problem (see below) and it compiles fine.
template <uint64_t left, uint64_t right>
constexpr uint64_t subtract()
{
return left - right;
}
template <uint64_t left, uint64_t right>
constexpr uint64_t GCD()
{
if constexpr (right == 0)
{
return left;
}
return GCD<right, left % right>();
}
template <uint64_t left, uint64_t right>
constexpr uint64_t LCM()
{
return (left * right) * GCD<left, right>();
}
template <uint64_t count, uint64_t accumulator = count>
constexpr uint64_t OneToNLCM()
{
static_assert(count > 0, "LCM doesn't quite make sense with 0 as a parameter");
if constexpr (count > 1)
{
//constexpr uint64_t val = ((left * (left - 1)) / GCD<left, left - 1>());
constexpr uint64_t numerator = (accumulator * (count - 1));
constexpr uint64_t denominator = GCD<accumulator, count - 1>();
return OneToNLCM<count - 1, numerator / denominator>();
}
return accumulator;
}
此外,如果我对原始代码进行了此修改,则visual studio将耗尽堆空间。
Also, if i make this modification to the original code, visual studio runs out of heap space.
template<uint64_t val, uint64_t counter = 0>
constexpr uint64_t CollatzChainLength()
{
if constexpr (val == 1)
{
return counter;
}
if constexpr (val % 2 == 0)
{
return CollatzChainLength<val / 2, counter + 1>();
}
return CollatzChainLength<val * 3 + 1, counter + 1>();
}
我知道用例非常简单,但它有点阻止我使用'constexpr if'时很难用简单的数学运算。
I know the use case is quite trivial, but it sort of discourages me from using 'constexpr if' when its hard to do simple math with it.
推荐答案
检查一下:
template<uint64_t val, uint64_t counter = 0>
constexpr uint64_t CollatzChainLength()
{
if constexpr ( val == 1 )
{
return counter;
}
else if constexpr ( val % 2 == 0 )
{
return CollatzChainLength<val / 2, counter + 1>();
}
else
{
return CollatzChainLength<val * 3 + 1, counter + 1>();
}
}
这篇关于constexpr如果太复杂(错误c1202)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!