根据C11标准,类函数宏的参数可以在其预处理标记序列的开头或结尾包含空格.对于正常更换,这种空间没有任何影响.对于字符串化,应忽略空格,如6.10.3.2.2中所述
第一个预处理标记之前和构成参数的最后一个预处理标记之后的空格被删除.
(我相信这也证明了参数可以在它周围有空格.)问题是,对于可以通过##运算符连接的参数,编译器应该对它的空格做什么?
我用VC++试了一下,似乎只是忽略了空格.
我认为编译器应该用空格执行连接.这可能导致无效的令牌,例如,由标识符ABC形成的"ABC"和具有空白空间作为第一令牌的参数.根据该标准,如果以这种方式形成无效令牌,则行为是未定义的.
那么对于VC++之前所做的事情,它是否只是忽略空间或未定义行为的结果?
c macros language-lawyer c-preprocessor preprocessor-directive
我想问的问题是:
(1)如果我通过剪贴板类与剪贴板交互,那么"嵌入源"和"MetaFilePict"流应该是什么?
(2)如果我通过COM接口IDataObject与剪贴板交互,我应该怎么处理"嵌入源"和"MetaFilePict"中的句柄?
(3)在C#中有更好的方法来实现OLE(客户端或服务器会帮助我)吗?
更多细节:
我正在寻求在C#中实现OLE服务器(外部Windows API和其他适用于x86的方法对我来说都可以,只要它们可以在一个C#项目中).我找不到任何不涉及MFC的OLE示例.所以我先尝试了一下.
我的第一步是查看其他OLE服务器执行哪些操作以将其数据放入剪贴板.我已经尝试了两种与剪贴板交互的方法:NET Clipboard类,它给我三个Streams,如后面所述,以及OleGetClipboard返回的IDataObject接口,它给了我指针.
我发现Origin放了三个数据条目:Object Descriptor,Embed Source和MetaFilePict.它们似乎是Stream.如果我从三个Streams读取所有字节,将它们放回到新的DataObject并再次将DataObject放到剪贴板中,我可以将原始对象粘贴到例如Word中,这意味着三个Streams的内容足够用于粘贴OLE容器.
我进一步发现,Object Descriptor包含带有数据类guid和一些名称的OBJECTDESCRIPTOR结构,我能够实例化该对象并将其转换为IOLEObject.但我不知道其他两个流,Embed Source和MetaFilePict应该是什么.根据我的理解,Embed Source应该包含在创建它之后传递给IOLEObject的数据(可能是由InitFromData),但是我没有成功.并且重新编写MetaFilePict,似乎没有这个条目,其他两个无法正常工作(如果只存在Object Descriptor和Embed Source,则粘贴到Word中最终没有任何内容).但同样,我不知道它里面是什么.它似乎以ASCII字符串开头(在我的例子中是"CPYA 4.2878 724#")并且看起来不像WMF文件.
如果我使用COM对象IDataObject(在System.Runtime.InteropServices.ComTypes或Microsoft.VisualStudio.OLE.Interop命名空间中),我可以从中获取HMETAFILEPICT,但我不知道如何使用该句柄.PlayMetaFile无法正常工作.
编辑
在MFC中,该示例使用OleCreateFromData直接从剪贴板获取的IDataObject创建对象.这应该也适用于C#.但这只是客户端的实现.我将尝试找出如何实现服务器.
我正在用C ++为新容器编写迭代器。当我调用begin()和end()函数(都很短)时,我希望编译器将其内联。但事实并非如此。我认为可能是因为迭代器作为临时对象返回,并且需要将其复制。我想也许我可以在c ++ 11中使用RValue引用,但是我对此并不熟悉。那么有没有办法使其内联?
代码是这样的(不完全相同,但是我认为如果此版本有效,我的代码也将有效)?
我正在使用VC ++ 2013 CTP,并且更改了编译选项,但是它也不起作用。
class Pointer
{
public:
Pointer(int* p) : p(p)
{
(*p)++;
}
Pointer(const Pointer& pointer) : p(pointer.p)
{
(*p)++;
}
Pointer& operator =(const Pointer& pointer)
{
(*p)--;
p = pointer.p;
(*p)++;
}
int* p;
~Pointer()
{
(*p)--;
}
static Pointer create(int& p)
{
return Pointer(&p);
}
static Pointer create2(int& p)
{
return create(p);
}
};
int main()
{
int p = 0;
Pointer pointer = Pointer::create2(p);
}
Run Code Online (Sandbox Code Playgroud)
您可以看到,这里的函数create和create2不是内联的,即使您确实很简单。
我知道这可能不会影响程序速度,但我只是想使其更好。