预处理程序命令中的sizeof不会编译,错误为C1017

时间:2019-07-03 04:34:17

标签: c++ preprocessor-directive

我想使用预处理器命令来控制代码执行路径。因为这样可以节省运行时间。

#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();
    }

4 个答案:

答案 0 :(得分:7)

预处理器在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

在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 :(得分:1)

C和C ++预处理器主要是一种出色的(不是那么出色的)文本替换引擎。它并不真正理解C或C ++代码。它不知道: 1000 :1000.2324422 :1000 ,也不知道C或C ++类型。 (当然不会知道模板类中的sizeof是什么。)

如果您想有条件地在TT上执行操作,则需要编写C ++代码来执行此操作(即,sizeof而不是{{1} }。

答案 2 :(得分:0)

正如评论中提到的@ some-programmer-dude一样,sizeof不是预处理程序的一部分。

如果您想在编译时使用if constexpr,则应该使用它。

如果您不在乎它是在编译时还是在运行时发生,只需使用常规的if语句

请记住,if constexpr是C ++ 17中的新功能!

答案 3 :(得分:0)

btw Borland C ++和Watcom C ++在预处理器表达式中支持sizeof(),我不知道gcc是否支持它。