c++ - 在模板参数包上使用类型特征?

标签 c++ templates c++17 typetraits parameter-pack

在下面的示例代码中,我尝试使用std::is_pointer检查函数参数是否为指针

如果只有一个参数,它可以正常工作,但是如何使其与更多参数一起使用,例如在参数包中?

#include <type_traits>
#include <iostream>

class Test
{
public:
    template<typename... Params>
    void f(Params... params);

    template<typename T, typename... Params>
    auto sum(T arg, Params... params)
    {
        return arg + sum(params...);
    }

    template<typename T>
    auto sum(T arg)
    {
        return arg;
    }

    int member = 1;
};

template<typename... Params>
void Test::f(Params... params)
{
    // ERROR: too many template arguments for std::is_pointer
    if constexpr (std::is_pointer_v<Params...>)
        member += sum(*params...);
    else
        member += sum(params...);

    std::cout << member;
}

int main()
{
    Test ts;

    // both fail
    ts.f(1, 2);
    ts.f(&ts.member, &ts.member);

    // is that even possible?
    ts.f(&ts.member, 2);

    return 0;
}

我猜如果参数不是全部不是指针,也不是全部不是指针,那么我们还有其他问题,但让我们假设所有参数都不是指针。

那如果参数仍然是指针和非指针的混合呢?

最佳答案

通过将对参数是否为指针的检测移到可变参数模板函数sum中,可以简化问题(并使程序正常运行)。

例:

#include <type_traits>
#include <iostream>

class Test
{
public:
    template<typename... Params>
    void f(Params... params)
    {
        member += sum(params...);

        std::cout << member << '\n';
    }

    template<typename... Params>
    auto sum(Params... params)
    {
        auto contents = [](auto param)
        {
            using ParamType = std::decay_t<decltype(param)>;
            if constexpr (std::is_pointer_v<ParamType>)
                return *param;
            else
                return param;
        };
        return (contents(params) + ...);
    }

    int member = 1;
};

int main()
{
    Test ts;

    // both fail
    ts.f(1, 2);
    ts.f(&ts.member, &ts.member);

    // is that even possible?
    ts.f(&ts.member, 2);

    return 0;
}

预期产量:
4
12
26

https://godbolt.org/z/y57-TA

关于c++ - 在模板参数包上使用类型特征?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59698976/

相关文章:

c++ - 使功能模板特化虚拟合法吗?

c++ - 无锁 fifo 缓冲区中的删除节点检测

c++ - 需要空终止的 string_view

c++为相同类型专门化类行为

c++ - 模板类与类模板

c++ - 纯右值的结果

c++ - 启动时自动初始化库

c++ - 如何知道要从子网掩码搜索哪些 IP 地址?

c++ - 使用 weak_ptr 实现观察者模式

java - 如何在 IDEA 的设置中修改整个默认的 "try-catch"模板?