简体   繁体   English

在C ++ 14中使用自动返回'type'进行显式模板特化是否有效?

[英]Is it valid to do explicit template specialisation with auto return 'type' in C++14?

Previous question . 上一个问题

I repeat the code from the previous question to make this question self-contained. 我重复上一个问题的代码,使这个问题自成一体。 The code below compiles and does not issue any warnings if it is compiled using gcc 4.8.3. 如果使用gcc 4.8.3编译,下面的代码将编译并不会发出任何警告。 with -std=c++1y . 使用-std=c++1y However, it does issue warnings if compiled with -std=c++0x flag. 但是,如果使用-std=c++0x标志进行编译,它会发出警告。 In the context of the previous question it was stated that the code does not compile using gcc 4.9.0. 在上一个问题的上下文中,声明代码不使用gcc 4.9.0进行编译。 Unfortunately, at present, I do not fully understand how auto is implemented. 不幸的是,目前我还不完全了解auto的实现方式。 Thus, I would appreciate if anyone could answer the following questions: 因此,如果有人能回答以下问题,我将不胜感激:

1). 1)。 Is the code below valid C++ with respect to the C++14 standard? 对于C ++ 14标准,代码下面的代码是否有效?

2). 2)。 If yes, would this code be considered a good style? 如果是的话,这段代码会被认为是一种好的风格吗? If not, why not? 如果没有,为什么不呢?

3). 3)。 Why does the code below compile and work (sometimes) when using C++11 compilers? 为什么下面的代码在使用C ++ 11编译器时编译和工作(有时)? Alternatively, why does it not always work? 或者,为什么它不总是有效? Are there any specific flags/options/settings that could prevent it from working? 是否有任何特定的标志/选项/设置可能阻止它工作?

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). 1)。 Is the code below valid C++ with respect to the C++14 standard? 对于C ++ 14标准,代码下面的代码是否有效?

Yes, as far as I can tell. 是的,据我所知。 It's sometimes a bit hard to prove, since often there's simply nothing forbidding it. 它有时候有点难以证明,因为通常没有什么可以禁止的。 However, we can look at an example in a recent draft (post-N4296), [dcl.spec.auto]/13: 但是,我们可以在最近的草案(后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 

The same paragraph specifies: 同一段落规定:

Redeclarations or specializations of a function or function template with a declared return type that uses a placeholder type shall also use that placeholder, not a deduced type. 具有使用占位符类型的声明返回类型的函数或函数模板的重新声明或特化也应使用该占位符,而不是推导类型。

So the explicit specializations of a function template must use return type deduction. 因此,函数模板的显式特化必须使用返回类型推导。 I cannot find anything that forbids different return types for different specializations. 我找不到任何禁止不同特殊化的不同返回类型的东西。 Similarly, in C++98, different return types for function template specializations (of the same primary template) can be achieved by making the return type dependent on the template arguments. 类似地,在C ++ 98中,通过使返回类型依赖于模板参数,可以实现函数模板特化(同一主模板)的不同返回类型。 By using metaprogramming, you can basically achieve the same as when using return type deduction to specify unrelated return types for the different specializations. 通过使用元编程,您基本上可以实现与使用返回类型推导来为不同的特化指定不相关的返回类型时相同。


3). 3)。 Why does the code below seem to compile and work (sometimes) using C++11 compilers? 为什么下面的代码似乎使用C ++ 11编译器编译和工作(有时)?

The code in the OP is ill-formed in C++11. OP中的代码在C ++ 11中是不正确的。 Return type deduction for ordinary functions (non-lamdas) is a feature introduced in C++14. 普通函数(非lamdas)的返回类型推导是C ++ 14中引入的一个特性。 A program that contains this code snippet is ill-formed . 包含此代码段的程序格式不正确 However, the Standard does not mandate that implementations (compilers) must reject ill-formed programs. 但是,该标准并未强制要求实施(编制者)必须拒绝不正当的程序。 It merely states in [intro.compliance]/2.2: 它只是在[intro.compliance] /2.2中说明:

If a program contains a violation of any diagnosable rule [...] a conforming implementation shall issue at least one diagnostic message. 如果程序包含违反任何可诊断规则的情况,则符合要求的实施方案应至少发出一条诊断消息。

and in /8 和/ 8

A conforming implementation may have extensions (including additional library functions), provided they do not alter the behavior of any well-formed program. 符合条件的实现可能具有扩展(包括其他库函数),前提是它们不会改变任何格式良好的程序的行为。 Implementations are required to diagnose programs that use such extensions that are ill-formed according to this International Standard. 需要实现来诊断使用根据本国际标准格式不正确的扩展的程序。 Having done so, however, they can compile and execute such programs. 但是,这样做之后,他们就可以编译和执行这样的程序。

(So implementations can accept this program as an extension .) (因此实现可以接受此程序作为扩展 。)

g++4.8.3 issues a warning, which counts as a diagnostic message. g ++ 4.8.3发出警告,该警告计为诊断消息。 g++4.9 issues an error, which is also a diagnostic message. g ++ 4.9发出错误,这也是一条诊断消息。 Both are compliant. 两者都符合要求。 By specifying -Werror , you could tell a g++4.8.3 to reject this program. 通过指定-Werror ,您可以告诉g ++ 4.8.3拒绝该程序。 (You'd have to ask the gcc developers why they've changed that from a warning to an error.) (您必须询问gcc开发人员为什么他们已将其从警告更改为错误。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM