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

时间:2016-11-18 16:03:08

标签: c++ templates compiler-warnings

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

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语句来消除警告。

问题:什么是清除警告的简洁方法?

4 个答案:

答案 0 :(得分:20)

我会尝试使用类似

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

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

答案 1 :(得分:6)

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

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

答案 2 :(得分:5)

正如你在对accepted answer的评论中所说,实际上没有直接回答问题,这是一个有用的解决方案,可以为将来的读者提供帮助。

要解决问题,您可以按照以下步骤定义功能模板:

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

答案 3 :(得分:4)

您可以使用GCC的__builtin_unreachable(在该链接上向下)向编译器传达给定行无法访问的情况,这将禁止该警告。 (我主要提到这个最终在这里的C开发者;对于C ++,上面使用delete的方法更好。)