预处理器命令中的 sizeof 无法编译并出现错误 C1017
sizeof in preprocessor command doesn't compile with error C1017
我想使用预处理器命令来控制代码执行路径。因为这样可以节省运行时间。
#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();
}
C 和 C++ 预处理器主要是一个美化(好吧,不是那么美化)的文本替换引擎。它并不真正理解 C 或 C++ 代码。它不知道 sizeof
,也不知道 C 或 C++ 类型。 (它肯定不知道模板 class 中的 T
是什么。)
如果你想在 T
和 sizeof
上有条件地做事,那么你需要编写 C++ 代码来完成它(即 if (...)
而不是 #if ...
.)
预处理器在 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";
}
}
};
C++17 之前的版本不太直接。您可以使用一些 partial-specialization 恶作剧。它不是特别漂亮,我认为在这种情况下它甚至不会更有效率,但在其他情况下可以应用相同的模式:
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();
}
};
在这种情况下,您可以直接特化 String
,但我假设在您的实际情况下,它还有您不想重复的其他成员。
正如评论中提到的@some-programmer-dude,sizeof
不是预处理器的一部分。
如果你想让它在编译时工作,你应该使用 if constexpr
。
如果您不关心它是在编译时发生还是 run-time 只需使用常规 if
语句
请记住,if constexpr
是 C++17 中的新功能!
顺便说一句,Borland C++ 和 Watcom C++ 支持预处理表达式中的 sizeof(),我不知道 gcc 是否支持。
我想使用预处理器命令来控制代码执行路径。因为这样可以节省运行时间。
#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();
}
C 和 C++ 预处理器主要是一个美化(好吧,不是那么美化)的文本替换引擎。它并不真正理解 C 或 C++ 代码。它不知道 sizeof
,也不知道 C 或 C++ 类型。 (它肯定不知道模板 class 中的 T
是什么。)
如果你想在 T
和 sizeof
上有条件地做事,那么你需要编写 C++ 代码来完成它(即 if (...)
而不是 #if ...
.)
预处理器在 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";
}
}
};
C++17 之前的版本不太直接。您可以使用一些 partial-specialization 恶作剧。它不是特别漂亮,我认为在这种情况下它甚至不会更有效率,但在其他情况下可以应用相同的模式:
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();
}
};
在这种情况下,您可以直接特化 String
,但我假设在您的实际情况下,它还有您不想重复的其他成员。
正如评论中提到的@some-programmer-dude,sizeof
不是预处理器的一部分。
如果你想让它在编译时工作,你应该使用 if constexpr
。
如果您不关心它是在编译时发生还是 run-time 只需使用常规 if
语句
请记住,if constexpr
是 C++17 中的新功能!
顺便说一句,Borland C++ 和 Watcom C++ 支持预处理表达式中的 sizeof(),我不知道 gcc 是否支持。