如何在使用static_assert时避免关于无返回表达式的警告

How to avoid warning about no return expression when using static_assert?

本文关键字:于无 返回 表达式 警告 static assert      更新时间:2023-10-16

我有两个库,为了方便,我在它们使用的一些类型/结构体之间编写了一个转换器。

template<typename T>
struct unsupportedType : std::false_type
{};
template<typename T>
FormatB getFormat()
{
    static_assert(
        unsupportedType<T>::value, "This is not supported!");
}
template<>
FormatB getFormat<FormatA::type1>()
{
    return FormatB(//some parameters);
}
template<>
FormatB getFormat<FormatA::type2>()
{
    return FormatB(//some other parameters);
}

现在,由于unsupportedType结构,编译器不会立即看到断言总是失败,因此如果没有在某处调用非专门化版本,则不会抛出编译错误。然而,编译器因此也不知道static_assert后面的返回语句是不必要的。我不只是想在断言之后放置一个任意的返回语句来摆脱警告。

问题:清除警告的干净方法是什么?

我会尽量避免使用static_assert,通过使用像

这样的东西
template<typename T> FormatB getFormat()=delete;

编译器编写者可以改进这些错误消息

退出函数的方法不止一种,return是一种,但throw是另一种:

template<typename T>
FormatB getFormat()
{
    static_assert(
        unsupportedType<T>::value, "This is not supported!");
    throw 0; // Unreachable
}

对于你在评论中说它实际上并没有直接回答问题,这里有一个可行的解决方案,可以帮助未来的读者。


要解决问题你可以定义你的函数模板如下:

template<typename T, typename R = void>
R getFormat()
{
    static_assert(
        unsupportedType<T>::value, "This is not supported!");
}

其他专门化不需要更改,类型R可以直接从返回类型推断出来。


下面是一个最小的工作示例,展示了它是如何工作的:

#include<type_traits>
template<typename T>
struct unsupportedType : std::false_type
{};
struct FormatA{
    using type1 = int;
    using type2 = char;
};
struct FormatB{};
template<typename T, typename R = void>
R getFormat()
{
    static_assert(
        unsupportedType<T>::value, "This is not supported!");
}
template<>
FormatB getFormat<FormatA::type1>()
{
    return FormatB();
}
template<>
FormatB getFormat<FormatA::type2>()
{
    return FormatB();
}
int main() {}

您可以使用GCC的__builtin_unreachable(它在该链接的下方)向编译器传达给定行不可达的信息,这将抑制该警告。(我主要是为那些最终在这里的C开发人员提到这一点;对于c++,使用上述delete的方法更好)。