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

NOh*_*Ohs 20 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);
}
Run Code Online (Sandbox Code Playgroud)

现在由于unsupportedType结构,编译器不会立即看到断言将始终失败,因此如果未在某处调用非专用版本,则不会抛出编译错误.但是,编译器因此也不知道返回语句之后static_assert是不必要的.我不只是想在断言之后放置一个任意的return语句来消除警告.

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

Han*_*son 20

我会尝试通过使用类似的东西来避免static_assert

template<typename T> FormatB getFormat()=delete;
Run Code Online (Sandbox Code Playgroud)

然后,编译器编写者可以改进这些错误消息.


Que*_*tin 6

退出函数有多种方法,returning是一种,但throwing是另一种方式:

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

  • @MrZ用某人的话说,"警惕墨菲,而不是马基雅维利" (4认同)
  • @MrZ我知道你已经决定了另一个答案,但是这里的未来访问者可能会想要一个`logic_error`:成功调用*应该*发出编译错误的函数表示程序逻辑中的错误,毕竟 (3认同)
  • @MrZ然后我建议`throw std :: runtime_error {"为什么你要试图打破我的TMP?"};`;) (2认同)

sky*_*ack 6

对于你在接受的答案评论中说它实际上没有直接回答这个问题,这是一个可以为未来的读者提供帮助的有效解决方案.


要解决此问题,您可以按照以下方式定义功能模板:

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

其他专业化不需要进行任何更改,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() {}
Run Code Online (Sandbox Code Playgroud)