gpt4 book ai didi

c++ - VS2017 [15.8.6]如果constexpr生成带有C2760消息的错误

转载 作者:行者123 更新时间:2023-12-02 10:58:31 30 4
gpt4 key购买 nike

自VS2017最新版本以来,此代码无法正常工作,而相同的代码在先前版本中构建良好:

inline std::tuple<float, float> _convertCentsToAlterAndCents (float shift);

using AccidentalVar = std::variant<std::nullopt_t, int, float, double, const char*, std::string, Accidental, Accidental::Ptr>;

void Pitch::accidental(AccidentalVar value)
{
std::visit([this](auto&& arg)
{
using T = std::remove_cv_t<std::remove_reference_t<decltype(arg)>>;

if constexpr (std::is_same_v<T, int> ||
std::is_same_v<T, float> ||
std::is_same_v<T, double>)
{
auto [alter, cents] = _convertCentsToAlterAndCents(static_cast<float>(arg) * 100.f);
_accidental = std::make_shared<Accidental>(alter);
if (abs(cents) > 0.01f)
microtone(cents);
}
else
if constexpr (std::is_same_v<T, const char*> ||
std::is_same_v<T, std::string>)
{
_accidental = std::make_shared<Accidental>(arg);
}
else
if constexpr (std::is_same_v<T, Accidental::Ptr>)
{
_accidental = (arg != nullptr) ? arg->deepcopy() : arg;
}
else
if constexpr (std::is_same_v<T, Accidental>)
{
_accidental = arg.deepcopy();
}
else
if constexpr (std::is_same_v<T, std::nullopt_t>)
{
_accidental = nullptr;
}
},
value);
}

错误是 C2760, unexcepted token '>'行中的 if (abs(cents) > 0.01f)

如果我删除 constexpr中的 if constexpr,则会出现 static_cast<float>问题,因为 arg (std::variant)可以是 std::nullopt(在访问者中进一步处理)。

为什么简单条件 abs(cents) > 0.01f无法建立?

非常感谢您的回答。

编辑:

也许我的问题与此有关:

constexpr

当条件评估操作的左侧操作数在constexpr上下文中无效时,Visual Studio 2017会正确引发错误。以下代码在Visual Studio 2015中编译,但不在Visual Studio 2017中编译(C3615 constexpr函数'f'无法导致常量表达式):
template<int N>
struct array
{
int size() const { return N; }
};

constexpr bool f(const array<1> &arr)
{
return arr.size() == 10 || arr.size() == 11; // C3615
}

要更正该错误,请将array::size()函数声明为constexpr或从f中删除constexpr限定符。

来源: https://docs.microsoft.com/fr-fr/cpp/cpp-conformance-improvements-2017?view=vs-2017#bug-fixes-in-visual-studio-versions-150-153update153-155update155-157update157-and-158update158

编辑2:
如果我注释 if (abs(cents) > 0.01f)行(在没有阈值条件的情况下调用 microtone(cents)),则代码构建良好。因此,虽然 0.01ffloat constantcentsfloat temporary variable,但是唯一的问题来自对 std::abs函数的调用。如我所见, std::abs不是constexpr函数。

如何在不编写内部有效的constexpr std::abs版本的情况下解决这一问题?

最佳答案

您是否看到过MS Developer错误报告https://developercommunity.visualstudio.com/content/problem/323938/broken-parsing-of-greater-than-comparison-operator.html

上面的错误似乎已在2019 Preview中修复。
但在此之前,如错误报告中所述。

最小化以上代码以重现vs 2017中的错误。
该修复程序按访问顺序说明...; if constexpr(...; if(...> ....)表达式由()引起来或>运算符的逆逻辑
注意:访问后的“>”;如果constexpr序列在其他情况下可能导致问题。

#include <tuple>
#include <variant>
#include <optional>

inline std::tuple<float, float> _convertCentsToAlterAndCents(float shift)
{
return std::tuple{shift, shift};
}
//using AccidentalVar = std::variant<std::nullopt_t, int, float, double, const char*, std::string, Accidental, Accidental::Ptr>;
using AccidentalVar = std::variant<std::nullopt_t, int, float, double, const char*>;

void microtone(float cents) {}

//void Pitch::accidental(AccidentalVar value)
void test(AccidentalVar value)
{
//std::visit([this](auto&& arg)
std::visit([&](auto&& arg)
{
using T = std::remove_cv_t<std::remove_reference_t<decltype(arg)>>;

if constexpr (std::is_same_v<T, int> ||
std::is_same_v<T, float> ||
std::is_same_v<T, double>)
{
auto[alter, cents] = _convertCentsToAlterAndCents(static_cast<float>(arg) * 100.f);
//_accidental = std::make_shared<Accidental>(alter);

//if (abs(cents) > 0.01f) // error in vs 2017
if ( ( abs(cents) > 0.01f ) ) // FIX 1 or
//if( 0.01f <= abs(cents) ) // or FIX 2
microtone(cents);
}
// remaining code removed...
},
value);
}

关于c++ - VS2017 [15.8.6]如果constexpr生成带有C2760消息的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52701439/

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