sizeof в команде препроцессора не компилируется с ошибкой C1017 - PullRequest
0 голосов
/ 03 июля 2019

Я хочу использовать команду препроцессора для управления исполнительным путем кода.Потому что таким образом можно сэкономить время выполнения.

#if (sizeof(T)==1 не завершается с ошибкой: C1017

template<typename T>
    class String
    {
    public:
        static void showSize()
        {
#if (sizeof(T)==1) 
            cout << "char\n";
#else
            cout << "wchar_t\n";
#endif
        }
    };

    inline void test()
    {
        String<char>::showSize();
        String<wchar_t>::showSize();
    }

Ответы [ 3 ]

7 голосов
/ 03 июля 2019

Препроцессор работает перед компилятором C ++.Он ничего не знает о типах C ++;только токены препроцессора.

Хотя я и ожидал, что любой приличный компилятор оптимизирует if (sizeof(T) == 1), вы можете быть откровенны в C ++ 17 с новым if constexpr:

template<typename T>
class String
{
public:
    static void showSize()
    {
        if constexpr (sizeof(T) == 1) {
            std::cout << "char\n";
        } else {
            std::cout << "wchar_t\n";
        }
    }
};

Live Demo

Pre C ++ 17 это немного менее просто.Вы можете использовать некоторые махинации с частичной специализацией.Это не особенно красиво, и я не думаю, что это будет даже более эффективно в этом случае, но тот же шаблон может быть применен в других ситуациях:

template <typename T, size_t = sizeof(T)>
struct size_shower
{
    static void showSize()
    {
        std::cout << "wchar_t\n";
    }
};

template <typename T>
struct size_shower<T, 1>
{
    static void showSize()
    {
        std::cout << "char\n";
    }
};

template<typename T>
class String
{
public:
    static void showSize()
    {
        size_shower<T>::showSize();
    }
};

Live Demo

В этом случае вы могли бы напрямую специализироваться String, но я предполагаю, что в вашей реальной ситуации есть другие участники, которые вам не нужно повторять.

1 голос
/ 03 июля 2019

Препроцессор C и C ++ - это, в основном, прославленный (ну, не такой славный) механизм замены текста. Он не совсем понимает код на C или C ++. Он не знает sizeof и не знает типов C или C ++. (Конечно, он не будет знать, что такое T из вашего шаблонного класса.)

Если вы хотите сделать что-то условно на T и на sizeof, то вам нужно написать код C ++, чтобы сделать это (то есть if (...) вместо #if ....)

0 голосов
/ 03 июля 2019

Как упомянуто в комментарии @ some-programmer-dude, sizeof не является частью препроцессора.

вы должны использовать if constexpr, если хотите, чтобы он работал во время компиляции.

если вам все равно, произойдет ли это во время компиляции или во время выполнения, просто используйте if регулярный

, помните, что if constexpr - это новая функция в C ++ 17!

...