C++ 如果constexpr和C4702(以及C4100和C4715)

C++ 如果constexpr和C4702(以及C4100和C4715),c++,visual-c++,c++17,if-constexpr,C++,Visual C++,C++17,If Constexpr,有没有办法解决以下问题: 此代码生成C4702警告“无法访问代码”(在VC++15.8上,使用/std:c++17) 添加的简单想法 else { return false; } 导致警告C4715“并非所有控制路径都返回值”。这是不可访问的,因为对于基于模板参数的模板的给定扩展,函数将仅通过条件并返回true或fail,然后返回false。对于同一类型,没有任何情况下它可以走任何一条路。它基本上扩展到了 if (true) { return tru

有没有办法解决以下问题:

此代码生成C4702警告“无法访问代码”(在VC++15.8上,使用
/std:c++17

添加的简单想法

    else
    {
        return false;
    }

导致警告C4715“并非所有控制路径都返回值”。

这是不可访问的,因为对于基于模板参数的模板的给定扩展,函数将仅通过条件并返回true或fail,然后返回false。对于同一类型,没有任何情况下它可以走任何一条路。它基本上扩展到了

if (true) {
  return true;
}
return false; // Obviously will never happen
我把它重写成只有一个返回语句

template <typename T, typename VariantType>
inline bool MatchMonostate( VariantType& variant )
{
    SUPPRESS_C4100( variant );
    bool retval = false;
    if constexpr ( std::is_same_v<T, std::monostate> )
    {
        variant = std::monostate();
        retval = true;
    }
    return retval;
}
模板
内联布尔匹配单状态(变量类型和变量)
{
抑制_C4100(变体);
bool-retval=false;
如果constexpr(std::is_same_v)
{
variant=std::monostate();
retval=true;
}
返回返回;
}

此外,在条件为真的情况下,变量不是未使用的。您可能希望将抑制警告(基本上变成(void)变体)的行移动到else语句。

作为直接问题的直接答案。关于
if constexpr
的主题。考虑这一点:

template <typename T, typename VariantType>
inline bool MatchMonostate( VariantType& variant )
{
    SUPPRESS_C4100( variant );
    bool retval = false;
    if constexpr ( std::is_same_v<T, std::monostate> )
    {
        variant = std::monostate();
        retval = true;
    }
    return retval;
}
template <typename T, typename ... params >
 inline bool match_monostate
  (std::variant<params ...> & variant) noexcept    
{
 if constexpr (std::is_same_v<T, std::monostate>)
 {
     variant = std::monostate{} ;
 //  compiles only if called with variant
 //  whose one alternative is std::monostate
     return true;
 }
 else {
    return false;
 }
}
如果constexpr()
生成false时,将生成此版本:

template <typename T, typename ... params >
 inline bool 
 match_monostate  (std::variant<params ...> & variant)  noexcept
{
    return false;
}
模板
内联布尔
匹配单状态(标准::变量和变量)无例外
{
返回false;
}
第二个版本可能会发出有关未使用参数的警告。但是(似乎)如果使用最新版本的clang/gcc/msvc,情况就不一样了。对于“old123987”等较旧的编译器,还指出可以将标准属性添加到签名中。像这样:

 template <typename T, typename ... params >
 inline bool 
 match_monostate  ([[maybe_unused]] std::variant<params ...> & variant) ;
模板
内联布尔
匹配单状态([[可能未使用]]std::variant&variant);

这将停止发出警告。

不过,我认为,现代编译器可以通过itself@old123987编译器确实找到了答案,并警告您该行无法访问=你的意思是除了回答问题之外?问题是关于一条线是无法到达的。这个答案解释了原因并更正了它。@ChefGladiator将一个东西转换为void以抑制“unused variable”警告在C++17之前(以及在C中)被广泛使用。它不是标准的,但我不会说它是“从标准的可移植C++中可以得到的”。据我所知,它是相当可移植的,应该可以在大多数体面的编译器上运行。OP说他在哪里尝试编写可移植代码?你不需要
suppress\u C4100
“技巧”。请看这里:。。在我的MSVC 19.15.26726Thx机器上也有同样的例子,可以指出这一点。只需使用
boolmatchmonostate([[maybe\u unused]]VariantType&variant)
就可以摆脱C4100。是的,这也很有效。虽然“三巨头”的最新版本甚至不需要这样做……但不确定哪一个是你的第三个。我的带有/std:c++最新版本的VC++15.8.3将在没有
[[maybe_unused]]
的情况下发布C4100。。。我可能遗漏了什么。。请转到devl命令提示符并执行“
cl/Bv
”。这将给出版本nums。我的是19.15.26726.0。。。我将在一个空的项目中重新尝试…您是否看到使用std::variant&vs只是VariantType&?(除了类型安全之外)我看不到所示的
match\u monostate
签名有任何明显的缺点。它还将阻止您这样做,例如:
match_monostate(变量{})
或使用const实例调用它…作为一种反小丑的措施,您可以删除以下声明:`template inline bool match_monostate(std::variant&&variant);=删除
,以停止它们使用移动的实例调用它
match_monostate(move(var))`
template <typename T, typename ... params >
 inline bool 
 match_monostate  (std::variant<params ...> & variant)  noexcept
{
    return false;
}
 template <typename T, typename ... params >
 inline bool 
 match_monostate  ([[maybe_unused]] std::variant<params ...> & variant) ;