使用 static_assert 时如何避免没有 return 表达式的警告?

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

我使用了两个库,为了方便起见,我在它们使用的一些 types/structs 之间编写了一个转换器。

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 之后的 return 语句是不必要的。我不只是想在断言之后放置一个任意的 return 语句来消除警告。

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

退出函数的方法不止一种,returning 是一种,throwing 是另一种:

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

我会尝试通过使用类似

的东西来避免static_assert
template<typename T> FormatB getFormat()=delete;

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

您可以使用 GCC 的 __builtin_unreachable(比 link 低)来通知编译器无法访问给定的行,这将抑制该警告。 (我主要是为最终来到这里的 C 开发人员提到这一点;对于 C++,上面使用 delete 的方法更好)。

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


要解决问题,您可以按如下方式定义函数模板:

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

其他特化不需要改变,类型R可以直接从return类型推导出来。


它遵循一个显示其工作原理的最小工作示例:

#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() {}