constexpr如果太复杂(错误c1202) [英] constexpr if too complicated (error c1202)

查看:80
本文介绍了constexpr如果太复杂(错误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>();
	}
}

当我尝试调用Collat​​zChainLength< 4,0>()时,我收到了c1202错误。但是,如果我删除计数器作为模板参数(是Collat​​zChainLength< val * 3 + 1,counter>(),现在是Collat​​zChainLength< 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆