功能模板重载解析度编译器优化 [英] Function Template Overload Resolution & Compiler Optimizations

查看:72
本文介绍了功能模板重载解析度编译器优化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在寻找在这里发现的这个问题模板函数重载对于包含类型的类型

I was looking at this question found here Template function overload for type containing a type

其中,OP user2079802 为他/她的问题提供了此代码:

Where the OP user2079802 provided this code for his/her question:


我正在尝试执行以下操作:

I'm trying to do the following:

#include <iostream>
#include <vector>
#include <tuple>

template <typename T>
void f(T t) {
    std::cout << "1" << std::endl;
}

template <typename T, typename V>
void f(T<std::tuple<V>> t) {
    std::cout << "2" << std::endl;
}

int main() {
    f(std::list<double>{}); // should use first template
    f(std::vector<std::tuple<int>>{}); // should use second template
}

在C语言中最简单的方法是什么++ 14?我以为我可以用这种方式进行模式匹配,但是编译器不会拥有它。

What is the simplest way to do this in C++14? I thought that I could sort of pattern match in this way but the compiler won't have it.

然后songyuanyao 提供了以下答案:


模板参数 T 用作模板名称,因此应将其声明为模板模板参数。例如,

The template parameter T is used as a template-name, so it should be declared as template template parameter. e.g.

template <template <typename...> class T, typename V>
//        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void f(T<std::tuple<V>> t) {
    std::cout << "2" << std::endl;
}

实时






提供的答案确实解决了编译错误,并且代码可以正确运行。为了清楚起见,我要问一个有关此代码段的问题。 OP最初试图对模板类型进行模式匹配,但是模板模板参数的语法不正确。当我通过我的IDE运行答案时,编译器和我在64位Intel Windows 7机器上运行的调试器{MSVS 2017 CE}碰巧发现,在OP的函数中调用了它们的主要功能:


The answer that was provided did in fact fix the compilation errors and the code does run correctly. I'm asking a question about this code snippet for clarity. The OP was originally trying to pattern match the template types but had improper syntax for template template parameters. When I ran the answer through my IDE, Compiler & Debugger {MSVS 2017 CE} running on a 64bit Intel Windows 7 machine I happen to notice that in the OP's function calls in their main function:


f(std::list<double>{});
f(std::vector<std::tuple<int>>{});


第二个函数调用实际上是在调用第一个函数模板而不是第二。这确实引起了几个问题:

That the 2nd function call is in fact calling the 1st function template and not the 2nd. This does raise a couple of questions:


  • 这是由于编译器优化而发生的吗?



  • 选择在第二个函数模板上使用第一个函数模板时,编译器实际上发生了什么?

  • 或者这是MSVC编译器的错误吗?

  • Is this happening due to compiler optimizations?
  • Is this a result of overload resolution?
  • What is actually happening under the hood of the compiler when it is choosing to use the first function template over the 2nd?
  • Or is this a bug with MSVC compiler?

推荐答案

实际上不是MSVC编译器中的错误。

It's not actually a bug in the MSVC compiler. It's really a result of an ambiguity in the standard concerning default template parameters.

您看到的 std :: vector 确实是标准含糊不清的结果。实际上有2个模板参数:类型和分配器。

You see, std::vector actually has 2 template arguments: the type, and an allocator.

如果重构该问题的答案以说明分配器

If you refactor the answer from that question to account for the allocator

template <typename T>
void f(T t) {
    std::cout << "1" << std::endl;
}

template <template <typename...> class T, typename V>
void f(T<std::tuple<V>, std::allocator<std::tuple<V>>> t) {
    std::cout << "2" << std::endl;
}

它将在所有编译器中正常工作: msvc演示 gcc演示 clang演示

It will work properly in all compilers: msvc demo, gcc demo, clang demo.

这是原始的缺陷报告(CWG 150)

P0522R0 的最新讨论截止到2016年11月,他们认为根据标准,您在Songyuanyao的答案中引用的部分模板匹配类型将是正确的。

P0522R0 has the latest discussion as of November 2016, where they propose that the kind of partial template matching you reference in songyuanyao's answer will be correct according to the standard.

P0522R0中提出的更改已合并到C ++ 17标准中(我检查的是草稿N4296)。在该标准定稿之前,MSVC声称拥有完整的C ++ 17支持,在编译器中我不会称其为错误。目前,他们承认从VS 2017.3 [P2]起,此特定建议尚未合并到其编译器中(

The changes proposed in P0522R0 are being incorporated into the C++17 standard (draft N4296 was the one I checked). Until the standard is finalized and MSVC claims to have full C++17 support, I wouldn't call it a bug in the compiler. For now, they acknowledge that this specific proposal has not yet been incorporated into their compiler as of VS 2017.3 [P2] (source)

这篇关于功能模板重载解析度编译器优化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆