c++ - 使用/解析模板时停止编译

标签 c++ gcc pragma

这个 MCVE:

#include <stdio.h>
#include <time.h>

#define MAX_LENGTH_DATETIME 25

template <typename T>
char * convertUnixTimeToChar( time_t unixTime, T )
{
    (void) unixTime;
    #pragma message "2nd parameter in convertUnixTimeToChar() must be of type <char [MAX_LENGTH_DATETIME]>."
    exit(1);
};

template<size_t N>
char * convertUnixTimeToChar( time_t unixTime, char (&destination) [N] )
{
    if ( N < MAX_LENGTH_DATETIME )
    {
        printf( "Overflow in convertUnixTimeToChar(): destination size [%ld] must be at least [%u]", N, MAX_LENGTH_DATETIME );
        exit(1);
    }
    struct tm * tmNow;
    tmNow = localtime( &unixTime );
    strftime( destination, MAX_LENGTH_DATETIME - 1, "%Y-%m-%d %H:%M:%S", tmNow );
    return destination;
};

int main()
{
    char buffer [MAX_LENGTH_DATETIME ];
    printf( "Converted unix time=%s\n", convertUnixTimeToChar( 1487585045, buffer ) );
}

我的问题:

我想显示消息 #pragma message "2nd parameter in convertUnixTimeToChar() must be of type <char [MAX_LENGTH_DATETIME]>." 来自 gcc 而编译仅当类型为char *的变量时已传递给convertUnixTimeToChar()因为第一个模板已解决。现在我总是收到这条消息。

换句话说,如果传递了错误的参数而不是在程序运行时编译应该失败[在这种情况下我必须使用printf而不是 #pragma得到通知]。

传递类似于 char [25] 的内容解析第二个模板,一切正常!

如果模板已物理用于代码生成,有没有一种方法可以有条件地停止编译并显示错误消息?

使用这些开关使用 gcc 4.9.4 编译:-Wall -Werror -Wextra -std=c++11 -O3

最佳答案

再一次,最佳解决方案是“什么都不做”。
完全删除 catch-all 重载将使编译器为任何不能匹配 char (&destination) [N] 的参数产生错误。

如果你想要花哨并添加你自己的错误消息,你可以在 catch-all 中使用依赖的 static_assert:

template <class..., class T>
constexpr T &&depend(T &&o) {
    return std::forward<T>(o);
}

template <typename T>
char *convertUnixTimeToChar( time_t, T&& )
{
    static_assert(depend<T>(false), "2nd parameter in convertUnixTimeToChar() must ...");
}

并不是说这可能不是一个更好的解决方案,因为您捕获了 convertUnixTimeToChar 的整个重载集并将其陷入硬错误,该死的 SFINAE。如果有人想为他们自己的类型添加重载,他们将必须确保他们的重载比这个爆炸性的包罗万象更好,这是痛苦多于收获。

关于c++ - 使用/解析模板时停止编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42342037/

相关文章:

c++ - 具有子矩阵类的特征引用

c++ - 为每个枚举器添加代码

c++ - 修复此编译错误 : identifier "and" is a special operator name in C++ [-Werror=c++-compat]?

c - 为什么某些 C 编译器会在奇怪的地方设置函数的返回值?

c - 静态与外部内在函数

GCC代码统计/分析

c++ - 带有#pragma comment(lib) 的相对路径

c++-cli - #pragma managed(push, on) 和 #pragma managed(push, off) 在 C++/CLI 中?

c++ - unordered_set<BSTR> 的哈希和等于函数