2017-02-20 66 views
0

这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()时,因为第1个模板已解析。现在我总是得到这个消息。

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

通过类似char [25]的东西解决了第二个模板,一切都很好!

有没有一种方法可以有条件地阻止编译错误消息,以防模板已被使用物理代码生成?

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

+0

为什么不只是删除全部过载? – Quentin

+0

@Quentin OMG。是的,在这种情况下,我从编译器得到一个错误信息:错误:没有匹配函数调用'convertUnixTimeToChar(int,char *&)'和'note:不匹配类型'char [N]'和'char *' ' - 即使这不是我想要的100%,但它满足了我的需求。写下您的评论作为答案,我接受它!可能是我想要一个非常明确的消息,但编译器错误也很明显! –

回答

2

再次,最佳的解决方案是“完全不按兵不动”。
完全删除catch-all过载将导致编译器为任何不匹配char (&destination) [N]的参数产生错误。

如果你想获得幻想,并添加自己的错误信息,您可以使用相关的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可能会被诅咒。如果有人想为自己的类型添加重载,他们将不得不确保他们比这种爆炸式的捕获更好的匹配,这比收益更加痛苦。