2017-02-20 5 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]>."из НКУ а компиляция только когда переменная типа char * была передана convertUnixTimeToChar(), потому что был разрешен первый шаблон. Теперь я всегда получаю это сообщение.

Другими словами, компиляция должна завершиться неудачей, если неправильный параметр передан, а не когда программа запущена [в этом случае я должен использовать printf вместо #pragma, чтобы получить уведомление].

Передача чего-то вроде char [25] разрешает второй шаблон, и все в порядке!

Есть ли способ, который я могу условно завершить компиляцию с сообщением об ошибке в случае, если шаблон был использован физически для генерации кода?

Собран с GCC 4.9.4 с помощью этих переключателей: -Wall -Werror -Wextra -std=c++11 -O3

+0

Почему бы просто не удалить перегрузку? – Quentin

+0

@Quentin OMG. Да, в этом случае я получаю сообщение об ошибке из компилятора 'error: no matching function for call to 'convertUnixTimeToChar (int, char * &)' и' note: mismatched types 'char [N]' и 'char *' '- Даже это не 100%, что я хотел, но он удовлетворяет мои потребности. Напишите свой комментарий в качестве ответа, и я принимаю его! Может быть, я хотел получить очень четкое сообщение, но ошибка компилятора также понятна! –

ответ

2

еще раз, оптимальное решение «ничего не делать вообще».
Удаление полной перегрузки приведет к тому, что компилятор выдаст ошибку для любого параметра, который не может соответствовать 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 проклят. Если кто-то хочет добавить перегрузки для своих типов, им придется убедиться, что их лучше, чем этот взрывной улов, который больше болит, чем выигрыш.

Смежные вопросы