ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

c – Variadic模板选择更常见的模板而不是重载

2019-08-23 21:07:16  阅读:164  来源: 互联网

标签:c c11 templates variadic-templates


想象一下这段代码:

#include <iostream>
void PrintInternal() {
    std::cout << std::endl;
}

template <typename T, typename...ARGS>
void PrintInternal(const T& head, const ARGS&...rest) {
    std::cout << head << " ";
    PrintInternal(rest...);
};

template <typename...ARGS>
void PrintInternal(const double& head, const ARGS&...rest) {
    std::cout << "DBL!!! " << head << " ";
    PrintInternal(rest...);
}

template <typename...ARGS>
void Print(const ARGS&...args) {
    PrintInternal(args...);
}

int main() {
    Print(1.1, 2, 3.3, 4);
    Print(0, 1.1, 2, 3.3, 4);
    return 0;
}

首次打印输出:

DBL!!! 1.1 2 3.3 4

我的期望是,它会输出DBL! 3.3之前或没有DBL !!!一点都不但为什么一个???

第二次打印输出:

0 1.1 2 3.3 4

为什么没有DBL !!!如果我们在第一个例子中有一个输出就像输出一样.

如何实现,对于每个双重,我将输出不同的部分专业化的东西?我想,简单的重载应该没问题……

链接到cpp.sh以查看编译结果 – > http://cpp.sh/42cz

解决方法:

查找PrintInternal()将找到两种类型的函数:

>在功能模板定义时可见的所有功能.
>函数模板的从属参数的关联命名空间中的所有函数.

在这种情况下,我们的所有参数都是基本类型,因此没有任何关联的命名空间.这使事情变得更容易.所以当我们开始时:

#include <iostream>
void PrintInternal() { // #1
    std::cout << std::endl;
}

template <typename T, typename...ARGS>
void PrintInternal(const T& head, const ARGS&...rest) { // #2
    std::cout << head << " ";
    PrintInternal(rest...); // <== (*)
};

template <typename...ARGS>
void PrintInternal(const double& head, const ARGS&...rest) { // #3
    std::cout << "DBL!!! " << head << " ";
    PrintInternal(rest...);
}

标记为PrintInteral()的调用只有两个候选:nullary函数(#1)和它自己(#2).另一个,更专业的PrintInteral()采用const double& (#3)尚未可见,因此从未被视为候选人.并不是#2比#3更受欢迎,只是它是唯一的选择.

如果你翻转两个重载的顺序,那么你会有一个不同的问题 – 你将无法找到#2!

这为您提供了一些选择:

>单独打印单个元素以打印所有元素.这样,你只需要重载PrintSingle(),这更容易.
>向前声明所有功能模板,使它们全部可见.
>引入另一个论点仅仅是为了最初应用的第二个要点.只是一个伪参数,只是用ADL进行名称查找.这个解决方案有时是必要的,但总是令人困惑:

namespace N {
    struct adl { };

    void PrintInternal(adl ) {
        std::cout << std::endl;
    }

    template <typename T, typename...ARGS>
    void PrintInternal(adl, const T& head, const ARGS&...rest) {
        std::cout << head << " ";
        PrintInternal(adl{}, rest...);
    }

    template <typename...ARGS>
    void PrintInternal(adl, const double& head, const ARGS&...rest) {
        std::cout << "DBL!!! " << head << " ";
        PrintInternal(adl{}, rest...);
    }
}

template <typename...ARGS>
void Print(const ARGS&...args) {
    PrintInternal(N::adl{}, args...);
}

标签:c,c11,templates,variadic-templates
来源: https://codeday.me/bug/20190823/1701157.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有