上一个问题 https://stackoverflow.com/questions/27629039/c-explicit-return-type-template-specialisation.
我重复上一个问题中的代码以使这个问题独立。如果使用 gcc 4.8.3 编译下面的代码,则可以编译并且不会发出任何警告。和-std=c++1y
。但是,如果使用以下命令编译,它确实会发出警告-std=c++0x
旗帜。在上一个问题的上下文中,有人指出该代码不能使用 gcc 4.9.0 进行编译。不幸的是,目前我还不完全明白如何auto
已实施。因此,如果有人能回答以下问题,我将不胜感激:
1).下面的代码是否符合 C++14 标准的有效 C++?
2)。如果是,这段代码会被认为是一个好的风格吗?如果没有,为什么不呢?
3)。为什么下面的代码在使用 C++11 编译器时可以编译并工作(有时)?或者,为什么它并不总是有效?是否有任何特定的标志/选项/设置可能会阻止它工作?
template<int N> auto getOutputPort2();
template<> auto getOutputPort2<0>();
template<> auto getOutputPort2<1>();
template<>
auto getOutputPort2<0>()
{
return std::unique_ptr<int>(new int(10));
}
template<>
auto getOutputPort2<1>()
{
return std::unique_ptr<string>(new string("qwerty"));
}
1).下面的代码是否符合 C++14 标准的有效 C++?
是的,据我所知。有时有点难以证明,因为通常没有什么禁止它。但是,我们可以看一下最近的草案(N4296 后)中的一个示例,[dcl.spec.auto]/13:
template <typename T> auto g(T t) { return t; } // #1
template auto g(int); // OK, return type is int
template char g(char); // error, no matching template
template<> auto g(double); // OK, forward declaration with
// unknown return type
同一段规定:
具有使用占位符类型的声明返回类型的函数或函数模板的重新声明或特化也应使用该占位符,而不是推导类型。
所以函数模板的显式特化must使用返回类型推导。
我找不到任何禁止不同专业的不同返回类型的内容。类似地,在 C++98 中,(同一主模板的)函数模板特化的不同返回类型可以通过使返回类型依赖于模板参数来实现。通过使用元编程,您基本上可以实现与使用返回类型推导为不同专业化指定不相关的返回类型时相同的效果。
3)。为什么下面的代码似乎可以(有时)使用 C++11 编译器进行编译和工作?
OP 中的代码在 C++11 中格式不正确。普通函数(非 lamda)的返回类型推导是 C++14 中引入的一项功能。包含此代码片段的程序是不规范的。然而,该标准并不强制执行(编译器)必须拒绝格式错误的程序。它仅在 [intro.compliance]/2.2 中指出:
如果程序包含违反任何可诊断规则的行为,则符合要求的实现应发出至少一条诊断消息。
和 /8
一致的实现可以具有扩展(包括附加的库函数),只要它们不改变任何格式良好的程序的行为。根据本国际标准,需要实施来诊断使用此类格式错误的扩展的程序。然而,这样做之后,他们就可以编译并执行此类程序。
(所以实现可以接受这个程序作为扩展.)
g++4.8.3 发出警告,该警告被视为诊断消息。 g++4.9 发出错误,这也是诊断消息。两者均符合规定。通过指定-Werror
,你可以告诉 g++4.8.3 拒绝这个程序。 (您必须询问 gcc 开发人员为什么他们将其从警告更改为错误。)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)