C++/WinRT 不兼容 Visual Studio 15.8 预览版3,它是 Windows SDK 17134 的一部分。

8

尝试编译以下代码:

#include <winrt/base.h>

int main() {}

使用以下编译器选项:

/permissive- /std:c++latest

最近发布的Visual Studio 15.8 预览版本3.0会导致以下编译错误:
1>------ Build started: Project: test1, Configuration: Debug x64 ------
1>Source.cpp
1>c:\program files (x86)\windows kits\10\include\10.0.17134.0\cppwinrt\winrt\base.h(2185): error C3861: 'from_abi': identifier not found
1>c:\program files (x86)\windows kits\10\include\10.0.17134.0\cppwinrt\winrt\base.h(2185): note: This diagnostic occurred in the compiler generated function 'conditional<_Test,T,_Ty2>::type winrt::impl::as(From *)'
1>        with
1>        [
1>            _Ty2=winrt::com_ptr<T>
1>        ]
1>c:\program files (x86)\windows kits\10\include\10.0.17134.0\cppwinrt\winrt\base.h(2209): error C3861: 'from_abi': identifier not found
1>c:\program files (x86)\windows kits\10\include\10.0.17134.0\cppwinrt\winrt\base.h(2209): note: This diagnostic occurred in the compiler generated function 'conditional<_Test,T,_Ty2>::type winrt::impl::try_as(From *) noexcept'
1>        with
1>        [
1>            _Ty2=winrt::com_ptr<T>
1>        ]
1>c:\program files (x86)\windows kits\10\include\10.0.17134.0\cppwinrt\winrt\base.h(3850): error C3861: 'from_abi': identifier not found
1>c:\program files (x86)\windows kits\10\include\10.0.17134.0\cppwinrt\winrt\base.h(3873): note: see reference to class template instantiation 'winrt::weak_ref<T>' being compiled
1>c:\program files (x86)\windows kits\10\include\10.0.17134.0\cppwinrt\winrt\base.h(2984): note: see reference to class template instantiation 'winrt::com_ptr<ILanguageExceptionErrorInfo2>' being compiled
1>c:\program files (x86)\windows kits\10\include\10.0.17134.0\cppwinrt\winrt\base.h(3054): note: see reference to class template instantiation 'winrt::com_ptr<IRestrictedErrorInfo>' being compiled
1>c:\program files (x86)\microsoft visual studio\preview\professional\vc\tools\msvc\14.15.26608\include\type_traits(616): note: see reference to class template instantiation 'std::basic_string_view<wchar_t,std::char_traits<wchar_t>>' being compiled
1>c:\program files (x86)\microsoft visual studio\preview\professional\vc\tools\msvc\14.15.26608\include\xstring(2124): note: see reference to class template instantiation 'std::is_convertible<const _StringViewIsh &,std::basic_string_view<wchar_t,std::char_traits<wchar_t>>>' being compiled
1>        with
1>        [
1>            _StringViewIsh=const wchar_t *
1>        ]
1>c:\program files (x86)\microsoft visual studio\preview\professional\vc\tools\msvc\14.15.26608\include\xstring(2122): note: see reference to variable template 'const bool conjunction_v<std::is_convertible<wchar_t const * const &,std::basic_string_view<wchar_t,std::char_traits<wchar_t> > >,std::negation<std::is_convertible<wchar_t const * const &,wchar_t const *> > >' being compiled
1>c:\program files (x86)\microsoft visual studio\preview\professional\vc\tools\msvc\14.15.26608\include\xstring(2281): note: see reference to alias template instantiation '_Is_string_view_ish<const wchar_t*>' being compiled
1>c:\program files (x86)\windows kits\10\include\10.0.17134.0\cppwinrt\winrt\base.h(6308): error C3861: 'to_abi': identifier not found
1>Done building project "test1.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

有什么解决方案吗?

你是否拥有支持的Windows SDK版本(版本10.0.17134.0(Windows 10,1803版)或更高版本)?请参阅from_abi文档 - 1201ProgramAlarm
我能够重现这个问题。看起来 C++/WinRT 的 17134 版本与 VS 2017(15.8 更新预览版 3)不兼容,即使没有使用“/permissive-”选项...可能是编译器问题,所以我会联系相关团队。 - Chuck Walbourn
还要注意,在使用VS 2017时,应该使用/std:c++17而不是/std:c++latest。你只需要C++17支持来使用C++/WinRT,而不是一些未来的C++20。 - Chuck Walbourn
这可能适用于C++/WinRT,但它并不是程序中唯一的组件。其他部分可能需要C++17中没有的功能。 - Alexander Bessonov
1
这个问题也发生在于2018年8月14日发布的Visual Studio 2017 15.8.0版本。答案表明,这是一个需要通过SDK更新来解决的问题,所以这不应该是一个惊喜。我只是留下这些信息,以防未来的访问者也遇到了这个问题(就像我一样),但他们没有使用Visual Studio预览版。 - IInspectable
目前,我通过安装和使用Windows 10 Preview SDK 10.0.17709.0来解决这个问题。 - Alexander Bessonov
2个回答

12

这是一个已知问题,在未来的Windows 10 SDK更新中将得到解决。

您可以通过完全关闭一致性模式(/permissive-)来解决它,或者通过在其他选项中添加 /Zc:twoPhase- 来保持其开启并禁用两阶段名称查找

对于使用C++/WinRT的VS 2017,应该使用/std:c++17而不是/std:c++latest以启用C++17而不必选择未来的草案更改。

更新: 此问题已在Windows 10 October 2018 Update SDK (17763)中得到解决。


组合/permissive- /Zc:twoPhase- /std:c++latest似乎可以工作,如果您的编译单元需要实验性功能。然而,对我来说不清楚为什么C++/WinRT没有使用它,因为它依赖于/提供协程,而这不是C++17的一部分。如果您知道情况,请告诉我发生了什么事? - IInspectable
1
C++/WinRT头文件需要内联命名空间支持C++17,但仅需要C++14的广义constexpr即可构建。强烈鼓励使用协程,但它实际上不是C++11、C++14或C++17的一部分。它通过/await标志启用。 - Chuck Walbourn
/permissive- 已经存在 - /Zc:twoPhase- 可以使用。 - noelicus
这里的“breaking”是什么意思? - Chuck Walbourn
@ChuckWalbourn 关闭符合模式会产生毁灭性的影响,例如运算符名称将停止工作。 - user7860670
据我所知,在C++/WinRT中没有使用需要符合模式(“/permissive-”)或两阶段名称查找(由“/permissive-”启用,可通过“/Zc:twoPhase-”单独关闭)的情况。它确实需要C++17模式(“/std:c++17”)。您特别指的是哪些运算符名称? - Chuck Walbourn

0
我做了一个小补丁来修复这个问题。它添加了一些前向声明,以便通过两阶段查找找到必要的名称,并添加了一个缺失的 "template" 关键字。
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\cppwinrt\winrt\base.h
2171a2172,2189
>     template <typename D, typename I, typename Enable = void>
>     struct producer;
> }
> 
> WINRT_EXPORT namespace winrt
> {
>     template <typename D, typename I>
>     D* from_abi(I const& from) noexcept;
> 
>   template <typename I, typename D, std::enable_if_t<std::is_base_of_v<Windows::Foundation::IUnknown, I>>* = nullptr>
>     impl::abi_t<I>* to_abi(impl::producer<D, I> const* from) noexcept;
> 
>     template <typename I, typename D, std::enable_if_t<std::is_base_of_v< ::IUnknown, I>>* = nullptr>
>     impl::abi_t<I>* to_abi(impl::producer<D, I> const* from) noexcept;
> }
> 
> namespace winrt::impl
> {
6244c6262
<     template <typename D, typename I, typename Enable = void>
---
>     template <typename D, typename I, typename Enable>
6353c6371
<     template <typename I, typename D, std::enable_if_t<std::is_base_of_v<Windows::Foundation::IUnknown, I>>* = nullptr>
---
>     template <typename I, typename D, std::enable_if_t<std::is_base_of_v<Windows::Foundation::IUnknown, I>>*>
6359c6377
<     template <typename I, typename D, std::enable_if_t<std::is_base_of_v< ::IUnknown, I>>* = nullptr>
---
>     template <typename I, typename D, std::enable_if_t<std::is_base_of_v< ::IUnknown, I>>*>
7189c7207
<             return root_implements_type::get_weak<D>();
---
>             return root_implements_type::template get_weak<D>();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接