警告C4090:'初始化':不同的'__unaligned'限定符

时间:2017-02-17 17:31:47

标签: c++ winapi visual-studio-2015

 void file_explore(std::wstring str) {
     ITEMIDLIST *pIDL = ILCreateFromPath(str.c_str());
     if ( NULL != pIDL ) {
         SHOpenFolderAndSelectItems(pIDL , 0 , 0 , 0);
         ILFree(pIDL);
     } else {
         std::wstring p = str.substr(0 , str.find_last_of('\\'));
         ShellExecute(NULL , L"explore" , p.c_str() , NULL , NULL , SW_SHOWNORMAL);
     }
 }    

上面的编译没有警告32位但64位我得到警告c4090然而文档:https://msdn.microsoft.com/en-us/library/k77bkb8d.aspx声明这是一个c错误,我将得到C2440 for c ++但我正在使用c ++。

抱怨的代码行是:

 ITEMIDLIST *pIDL = ILCreateFromPath(str.c_str());

如何解决64位版本的此问题?

1 个答案:

答案 0 :(得分:2)

LPITEMIDLIST定义为typedef ITEMIDLIST __unaligned *LPITEMIDLIST,因此将结果视为ITEMIDLIST *会丢失__unaligned修饰符。我不确定这与32位还是64位有什么关系。

正如Hans Passant评论的那样,使用typedef解决了这个问题。在我的情况下,我使用std::unique_ptr,它需要基类型而不是指针,所以我需要一个非指针typedef。因为对于那些绊倒这个答案的人来说可能有一点兴趣,我将介绍如何使用std::unique_ptrILCreateFromPath,包括自定义删除器以获取乐趣:

auto deleter = [](LPITEMIDLIST ptr) { ILFree(ptr); };
using itemidlistptr_t = std::unique_ptr<
    std::remove_ptr_t<LPITEMIDLIST>, decltype(deleter)>;
auto dir = itemidlistptr_t(ILCreateFromPathW(folder.c_str()), deleter);

使用std::remove_pointer_t有点迂回,但我喜欢这里,而不是直接提及__unaligned