sizeof in preprocessor command doesn't compile with error C1017

后端 未结 4 616
迷失自我
迷失自我 2021-01-29 16:46

I want to use preprocessor command to control code executive path. Because in this way can save runtime time.

#if (sizeof(T)==1 doesn\'t comple with error:

相关标签:
4条回答
  • 2021-01-29 16:58

    The C and C++ preprocessor is mostly a glorified (well, not that glorious) text replacement engine. It doesn't really understand C or C++ code. It doesn't know sizeof, and it doesn't know C or C++ types. (It certainly won't know what T from your template class is.)

    If you want to do things conditionally on T and on sizeof, then you'll need to write C++ code to do it (i.e., if (...) instead of #if ....)

    0 讨论(0)
  • 2021-01-29 17:00

    btw Borland C++ and Watcom C++ support sizeof() in preprocessor expressions, I do not know whether gcc support it.

    0 讨论(0)
  • 2021-01-29 17:08

    The preprocessor runs before the C++ compiler. It knows nothing of C++ types; only preprocessor tokens.

    While I would expect any decent compiler to optimize away an if (sizeof(T) == 1), you can be explicit about it in C++17 with the new 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 it's a bit less straightforward. You could use some partial-specialization shenanigans. It's not particularly pretty, and I don't think it will even be more efficient in this case, but the same pattern could be applied in other situations:

    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

    In this case you could directly specialize String, but I'm assuming in your real situation it has other members that you don't want to have to repeat.

    0 讨论(0)
  • 2021-01-29 17:18

    As @some-programmer-dude mentioned in the comment, sizeof is not part of the preprocessor.

    you should use if constexpr if you want it to work in compile time.

    if you don't care if it happens in compile time or run-time just use a regular if statment

    keep in mind that if constexpr is a new feature in C++17!

    0 讨论(0)
提交回复
热议问题