如何去除这种重复

问题描述 投票:0回答:2

我有这样的代码:

struct A1{
    void do_something1(int t, ... ){
        switch(t){
            default:
            case  8: return process_<uint8_t >(a, b, c);
            case 16: return process_<uint16_t>(a, b, c);
            case 32: return process_<uint32_t>(a, b, c);
            case 64: return process_<uint64_t>(a, b, c);
        }
    }
       
    template<typename T>
    void process_(...){
    }
};
    
struct A2{
    void do_something2(int t, ... ){
        switch(t){
            default:
            case  8: return process_<uint8_t >(d, e, f);
            case 16: return process_<uint16_t>(d, e, f);
            case 32: return process_<uint32_t>(d, e, f);
            case 64: return process_<uint64_t>(d, e, f);
        }
    }
       
    template<typename T>
    void process_(...){
    }
};

几个具有相似开关的类将相同的参数“转发”到另一个使用模板参数而不是方法参数的方法

t
.

目前,如果我需要更改

process_
的参数,我需要写4次。

有没有简单的方法可以删除这个重复项?
例如而不是 4 行几乎相同的行,只有 1-2 行代码。

switch(t){
    default:
    case  8: return process_<uint8_t >(d, e, f);
    case 16: return process_<uint16_t>(d, e, f);
    case 32: return process_<uint32_t>(d, e, f);
    case 64: return process_<uint64_t>(d, e, f);
}

我可以考虑指向方法的指针,但我不确定该怎么做。

c++ templates dry
2个回答
3
投票

您可以制作一个辅助函数来“提升”运行时值

t
为四种类型之一,并将其传递给lambda:

// C++20 version
template<typename Lambda>
void select_type(int t, const Lambda& l) {
    switch (t) {
        default:
        case 8 : l.template operator()<std::uint8_t >();
        case 16: l.template operator()<std::uint16_t>();
        case 32: l.template operator()<std::uint32_t>();
        case 64: l.template operator()<std::uint64_t>();
    }
}


void do_something1(int t, ... ) {
    select_type(t, [&]<typename T> {
        process_<T>(a, b, c);
    });
}
// C++14/17 version
template<typename T>
struct type_identity {
    using type = T;
};

template<typename Lambda>
void select_type(int t, const Lambda& l) {
    switch (t) {
        default:
        case 8 : l(type_identity<std::uint8_t >{});
        case 16: l(type_identity<std::uint16_t>{});;
        case 32: l(type_identity<std::uint32_t>{});;
        case 64: l(type_identity<std::uint64_t>{});;
    }
}

void do_something1(int t, ... ) {
    select_type(t, [&](auto t) {
        using T = typename decltype(t)::type;
        process_<T>(a, b, c);
    });
}

1
投票

我可以考虑指向方法的指针,但我不确定该怎么做。

这样的事情应该有效:

int whichOne(int t) {
    switch(t){
        default:
        case  8: return 0;
        case 16: return 1;
        case 32: return 2;
        case 64: return 3;
    }
}

struct A1{
    template<typename T>
    void process_(...){
    }

    void do_something1(int t, ...){
        using MethodType = void (A1::*)(...);
        static const MethodType methods[] = {
            &A1::process_<uint8_t >,
            &A1::process_<uint16_t>,
            &A1::process_<uint32_t>,
            &A1::process_<uint64_t>
        };
        (this->*methods[whichOne(t)])(a, b, c);
    }
};
    
struct A2{
    template<typename T>
    void process_(...){
    }

    void do_something2(int t, ...){
        using MethodType = void (A2::*)(...);
        static const MethodType methods[] = {
            &A2::process_<uint8_t >,
            &A2::process_<uint16_t>,
            &A2::process_<uint32_t>,
            &A2::process_<uint64_t>
        };
        (this->*methods[whichOne(t)])(d, e, f);
    }
};
© www.soinside.com 2019 - 2024. All rights reserved.