【问题标题】:Win32 programming can not include template header fileWin32编程不能包含模板头文件
【发布时间】:2019-03-13 05:13:55
【问题描述】:

我正在使用 Visual Studio 2017 编写一个标准的 Win32 Windows UI 程序。但是当我尝试将以下头文件包含到 MyMainWin.cpp 文件(您在其中定义窗口和消息处理)时,它抱怨了许多语法错误。例如,对于类定义“};”末尾的行,它抱怨“在';'之前出现意外的标记”。如果我将以下头文件包含到控制台应用程序 main.cpp 中,它工作正常。为什么?

#ifndef _MY_RAND_H_
#define _MY_RAND_H_

#include <random>
#include <tuple>
#include <iostream>

namespace myown {

void srand(int seed);
int rand();

template<class IntType = int>
class my_uniform_int_distribution {
public:
// types
typedef IntType result_type;
typedef std::pair<int, int> param_type;

// constructors and reset functions
explicit my_uniform_int_distribution(IntType a = 0, IntType b = std::numeric_limits<IntType>::max());
explicit my_uniform_int_distribution(const param_type& parm);
void reset();

// generating functions
template<class URNG>
result_type operator()(URNG& g);
template<class URNG>
result_type operator()(URNG& g, const param_type& parm);

// property functions
result_type a() const;
result_type b() const;
param_type param() const;
void param(const param_type& parm);
result_type min() const;
result_type max() const;

private:
typedef typename std::make_unsigned<IntType>::type diff_type;

IntType lower;
IntType upper;
}; //visual studio compiler complains "unexpected token(s) preceding';'" here

//method definition...
}
#endif

【问题讨论】:

  • 命名空间没有结束 }。

标签: templates winapi


【解决方案1】:

您可能遇到问题是因为您使用了std::numeric_limits&lt;IntType&gt;::max()。 windows.h 最终包含一个文件minwindef.h,它定义了不幸的宏max 和min。来自minwindef.h的片段:

#ifndef NOMINMAX

#ifndef max
#define max(a,b)            (((a) > (b)) ? (a) : (b))
#endif

#ifndef min
#define min(a,b)            (((a) < (b)) ? (a) : (b))
#endif

#endif  /* NOMINMAX */

如果windows.h 包含在您的自定义标头之前,则std::numeric_limits&lt;IntType&gt;::max() 表达式将扩展为std::numeric_limits&lt;IntType&gt;::((() &gt; ()) ? () : ()),这是无效的语法。

有两种可能的解决方案:

  • #define NOMINMAX 在包含 windows.h 之前 - 通常这是一个很好的做法,因为这些 min/max 宏(以及它们的非 Windows 形式 MIN 和 MAX)是问题的已知原因
  • 在 windows.h 之前包含您的自定义标头 - 这不是最好的方法,因为它需要您的自定义标头的用户有一些额外的知识

【讨论】:

  • 第一个解决方案确实解决了我的问题。非常感谢您的帮助。
猜你喜欢
  • 2014-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-11
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
相关资源
最近更新 更多