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

Use*_*666 2 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);
     }
 }    
Run Code Online (Sandbox Code Playgroud)

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

抱怨的代码行是:

 ITEMIDLIST *pIDL = ILCreateFromPath(str.c_str());
Run Code Online (Sandbox Code Playgroud)

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

McM*_*ard 6

LPITEMIDLIST定义为typedef ITEMIDLIST __unaligned *LPITEMIDLIST,因此接受结果为ITEMIDLIST *会丢失该__unaligned修饰符。我不确定这与 32 位和 64 位有何关系。

正如 Hans Passant 评论的那样,使用 typedef 解决了这个问题。就我而言,我使用的是std::unique_ptr,它需要基本类型而不是指针,因此我需要一个非指针 typedef。因为对于偶然发现这个答案的人来说可能不太感兴趣,所以我将介绍我如何使用 with 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);
Run Code Online (Sandbox Code Playgroud)

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