当前位置:  开发笔记 > 编程语言 > 正文

标签调度,可变参数模板,通用引用和错过的const说明符

如何解决《标签调度,可变参数模板,通用引用和错过的const说明符》经验,为你挑选了1个好方法。

请考虑以下示例(标签调度,可变参数模板,完美转发等等):

#include 
#include 
#include 

struct A { };
struct B { };

void doIt(A&&, const std::string &) {
    std::cout << "A-spec" << std::endl;
}

template
void doIt(T&&, Args&&...) {
    std::cout << "template" << std::endl;
}

template
void fn(Args&&... args) {
    doIt(T{}, std::forward(args)...);
}

int main() {
    const std::string foo = "foo";
    std::string bar = "bar";
    fn(foo);
    fn(bar);
    fn(foo);
}

在这种情况下,输出是:

A-spec
template
template

原因很明显,它并没有打扰我.

我想要实现的是doIt在两种情况下调用函数的第一个实例,无论字符串是否具有const说明符.
当然,一个可能的解决方案是doIt使用正确的原型定义一个新的,无论如何我想知道是否还有另一个解决方案.

到目前为止,我已经试图通过它来获得它add_const,但我很确定我错过了一些东西.
有没有可行的解决方案来静默添加const说明符并让它工作?

编辑

我已经更新了上面的例子,以便更加符合真正的问题.
此外,尽管有趣的答案,我忘了引用这只是一个简化的例子,所以真正的问题不仅仅涉及std::string.相反,它可能发生(作为示例)标记A参数是intconst std::string &,而对于标记B,参数是float,类的实例C,等等.
因此,试图以某种方式解决问题的那些答案std::string将无法解决真正的问题,对不起.



1> Piotr Skotni..:

引入两个独立的函数,以便它们不会相互冲突,编译器不会引起任何歧义错误:

void doIt(A&&, const std::string &)
{
    std::cout << "A-spec" << std::endl;
}

template 
void doIt_template(T&&, Args&&...)
{
    std::cout << "template" << std::endl;
}

优先考虑两个额外的重载; 首选的是尝试调用目标函数的专用非模板化版本:

template 
auto fn_impl(int, Args&&... args)
    -> decltype(doIt(T{}, std::forward(args)...), void())
{
    doIt(T{}, std::forward(args)...);
}

template 
void fn_impl(char, Args&&... args)
{
    doIt_template(T{}, std::forward(args)...);
}

介绍一个单一的通用调度员:

template 
void fn(Args&&... args)
{
    fn_impl(0, std::forward(args)...);
}

DEMO

推荐阅读
无名有名我无名_593
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有