C++11 类的方法(在共享的_ptr中)可以绑定到traits类中的静态函数吗?

C++11 类的方法(在共享的_ptr中)可以绑定到traits类中的静态函数吗?,c++11,generic-programming,C++11,Generic Programming,历史上,我一直使用trait类来保存信息,并将其应用到运行相同“算法”的“泛型”函数中。只是trait类不同。例如: enum选择器{SELECTOR1,SELECTOR2,SELECTOR3,}; //声明 模板struct-example\u-trait; 模板结构示例_trait{ 静态constexpr size\u t member\u var=3; 静态大小\u t do\u something(){return 0;} }; 模板结构示例_trait{ 静态constexpr si

历史上,我一直使用trait类来保存信息,并将其应用到运行相同“算法”的“泛型”函数中。只是trait类不同。例如:

enum选择器{SELECTOR1,SELECTOR2,SELECTOR3,};
//声明
模板struct-example\u-trait;
模板结构示例_trait{
静态constexpr size\u t member\u var=3;
静态大小\u t do\u something(){return 0;}
};
模板结构示例_trait{
静态constexpr size\u t member\u var=5;
静态大小\u t do\u something(){return 0;}
};
//假装这是在做一些有用但普通的事情
模板
void函数(){
标准::cout
int执行_操作(…)
{
返回TT::第一个函数(..)+TT::第二个函数(..);
}
理想情况下,我想修改上面的类,使之符合

    // Inside setter class further above
    int get_thing_a()
    {
        return perform_action<THINGA>(...);
    }

    int get_thing_b()
    {
        return perform_action<THINGB>(...);
    }
//上面的setter类内部
int get_thing_a()
{
返回执行操作(…);
}
int get_thing_b()
{
返回执行操作(…);
}

答案是,也许我不能,我需要将int作为一个参数传递给shared_ptr,并调用我需要的特定方法,而不是试图将shared_ptr方法绑定到一个静态函数(事后看来,这听起来不是一个好主意……但我想反驳我的想法)无论谁进行实际调用,都需要对象的引用,不管是哪种方式。因此,假设您希望
perform\u action
执行实际调用,则必须传递参数

现在,如果您确实想在
thing\u traits
中存储要作为
静态
调用的
Base
的哪个函数而不传递参数,您可以利用指向成员函数的指针:

template <>
struct thing_traits<THINGA>
{
    static constexpr int (Base::*first_function)() = &Base::get_thing_one;
    ...
}

template < thing_select T,  typename TT = thing_traits<T>>
int perform_action(Base & b)
{
   return (b.*TT::first_function)() + ...;
}
模板
结构物特征
{
静态constexpr int(Base::*first_function)(=&Base::get_thing_one;
...
}
模板
内部执行行动(基本和b)
{
返回(b.*TT::first_函数)(+。。。;
}
您也可以使用返回一个函数对象来代替调用(内部函数接受参数)


这完全取决于您需要调用谁,以及您认为在每个类/模板中都有哪些可用的信息/依赖项。

您能提供一个返回执行调用的函数对象的快速示例吗?我认为执行操作必须传递该对象,而该对象将传入函数对象参数。@user1945925在C++11中使用lambda是否合适?如果是,只需从
第一个\u函数()
返回一个,然后在
执行\u操作()
中调用lambda。当然,您需要将参数传递给lambda,但不需要将其传递给
第一个\u函数()
// example simple factory
std::shared_ptr<Base> get_class(const int input) {
    switch(input)
    {
        case 0:
            return std::shared_ptr<Base>(std::make_shared<A>());
        break;

        case 1:
            return std::shared_ptr<Base>(std::make_shared<B>());
        break;

        default:
            assert(false);
        break;
    }
}
// class that uses the shared_ptr
class setter {
    private:

    std::shared_ptr<Base> l_ptr;

    public:

    setter(const std::shared_ptr<Base>& input):l_ptr(input)
    {}

    int get_thing_a()
    {
        return l_ptr->get_thing_one() +  l_ptr->get_thing_two();
    }

    int get_thing_b()
    {
        return l_ptr->get_thing_three() +  l_ptr->get_thing_four();
    }
};

int main()
{
    constexpr int select = 0;
    std::shared_ptr<Base> example = get_class(select);
    setter l_setter(example);

    std::cout << l_setter.get_thing_a() << std::endl;
    std::cout << l_setter.get_thing_b() << std::endl;

    return 0;
}
enum thing_select { THINGA, THINGB, };

template < thing_select T >
struct thing_traits;

template <>
struct thing_traits<THINGA>
{
     static int first_function() --> somehow tied to shared_ptr<Base> 'thing_one' method
     static int second_function() --> somehow tied to shared_ptr<Base> 'thing_two' method
}

template <>
struct thing_traits<THINGB>
{
     static int first_function() --> somehow tied to shared_ptr<Base> 'thing_three' method
     static int second_function() --> somehow tied to shared_ptr<Base> 'thing_four' method
}

// generic function I'd like to create
template < thing_select T, typename TT = thing_traits<T> >
int perform_action(...)
{
   return TT::first_function(..) + TT::second_function(..);
}
    // Inside setter class further above
    int get_thing_a()
    {
        return perform_action<THINGA>(...);
    }

    int get_thing_b()
    {
        return perform_action<THINGB>(...);
    }
template <>
struct thing_traits<THINGA>
{
    static constexpr int (Base::*first_function)() = &Base::get_thing_one;
    ...
}

template < thing_select T,  typename TT = thing_traits<T>>
int perform_action(Base & b)
{
   return (b.*TT::first_function)() + ...;
}