【发布时间】:2021-11-14 09:26:23
【问题描述】:
当我忽略输入 typename 关键字时,是否可以更改 Visual Studio (2019) 构建设置以使下面的第一行无法编译。因为 GCC 一直抱怨它是必需的,没有它就无法构建。
auto v = std::dynamic_pointer_cast<T::element_type>(sp); // Builds in VS, fails in GCC
auto v = std::dynamic_pointer_cast<typename T::element_type>(sp);// Builds in both VS and GCC
注意:
-
sp是shared_ptr<Base> -
T是shared_ptr<Derived> -
Derived派生自Base
我已经将 VS 语言标准设置为 C++17 (/std:c++17),警告级别设置为 4 (/W4) 并开启了完全兼容性 (/permissive-)。但是 Visual Studio 仍然允许这条线通过。由于缺少typename,GCC(版本 10.3 设置为 C++17)将无法编译
我不在乎哪个编译器对仍然需要的关键字是正确的。关键是它是合法的,不管它是不是多余的。如果可能的话,我只是想通过构建开关强制他们就该主题达成一致。
另外,如果根据未来的 C++ 17 标准不再真正需要该关键字,那么我是否可以翻转 GCC 构建设置以允许代码行在没有关键字的情况下通过?
[编辑]
我在这里添加了一个最小的可重现示例。很抱歉最初没有把它放进去,但我主要是要求编译器标志或其他东西,所以我认为没有必要。以下代码使用我提到的编译器设置在 VS 2019 16.11.3 上构建得很好。诚然,这是人为的,但我根据实际代码改编了它,这非常多毛……
#include <stdexcept>
#include <type_traits>
#include <memory>
class Base
{
public :
Base() {}
virtual ~Base() {}
};
using BasePtr = std::shared_ptr<Base>;
class Derived : public Base
{
};
using DerivedPtr = std::shared_ptr<Derived>;
template<class T>
typename std::enable_if<std::is_convertible<T, BasePtr>::value, T>::type
getAsT(BasePtr sp)
{
const auto out = std::dynamic_pointer_cast<T::element_type>(sp);
if (nullptr == out)
throw std::runtime_error("Not the right type");
return out;
}
int main()
{
auto derived = std::make_shared<Derived>();
auto derived2 = getAsT<DerivedPtr>(derived);
}
【问题讨论】:
-
// Builds in both VS and GCC有什么问题? -
您是否已经检查过 clang 在这方面的表现? (我不知道它是否与 gcc 一起使用。)因此,您可以在签入之前添加一个带有 clang 的工具链,以便在 Windows/Visual Studio 中进行检查。(我不知道更好的工作流程。我是曾经在虚拟机中检查我在 Debian 中的代码库,但和你一样,我经常忘记这样做之前提交...)
-
@463035818_is_not_a_number 是的。使 MSVC 抱怨的 MSVC 标志或使 GCC not 抱怨的 GCC 构建标志。只要语言合法
-
尝试编译使用
/Za标志? docs.microsoft.com/en-us/cpp/build/reference/… -
@Joe Compiler Explorer 是一个方便的工具,可以解决像您这样的问题。 (我曾经用它来了解MSVC的
/permissive-选项的意义:Compiler Explorer: Conformance Test。);-)
标签: c++ visual-studio gcc c++17