class(在 shared_ptr 中)的方法可以绑定到特征 class 中的静态函数吗?
Can a method of an class (in a shared_ptr) be tied to a static function in a traits class?
从历史上看,我一直使用特征 classes 来保存信息并将其应用到运行相同 "algorithm." 的 "generic" 函数中,只是特征 [=48] 不同=].例如:https://onlinegdb.com/ryUo7WRmN
enum selector { SELECTOR1, SELECTOR2, SELECTOR3, };
// declaration
template < selector T> struct example_trait;
template<> struct example_trait<SELECTOR1> {
static constexpr size_t member_var = 3;
static size_t do_something() { return 0; }
};
template<> struct example_trait<SELECTOR2> {
static constexpr size_t member_var = 5;
static size_t do_something() { return 0; }
};
// pretend this is doing something useful but common
template < selector T, typename TT = example_trait<T> >
void function() {
std::cout << TT::member_var << std::endl;
std::cout << TT::do_something() << std::endl;
}
int main()
{
function<SELECTOR1>();
function<SELECTOR2>();
return 0;
}
在处理多态 classes 时,我不确定如何创建 "generic" 算法。
例如:https://onlinegdb.com/S1hFLGC7V
下面我创建了一个继承的 class 层次结构。在此示例中,我有一个基本的包罗万象的示例,它将所有参数默认为某个值(在本例中为 0)。然后每个派生 class 集覆盖特定方法。
#include <iostream>
#include <memory>
#include <type_traits>
#include <assert.h>
using namespace std;
struct Base {
virtual int get_thing_one() {
return 0;
}
virtual int get_thing_two() {
return 0;
}
virtual int get_thing_three() {
return 0;
}
virtual int get_thing_four() {
return 0;
}
};
struct A : public Base {
virtual int get_thing_one() override {
return 1;
}
virtual int get_thing_three() override {
return 3;
}
};
struct B : public Base {
virtual int get_thing_one() override {
return 2;
}
virtual int get_thing_four() override{
return 4;
}
};
这里我创建了一个简单的工厂,虽然不够优雅,但仅供说明之用
// 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 的兴趣所在。它是 class 对上面 classes 中的数据执行 "something"。下面的方法是一个简单的加法示例,但想象一个更复杂的算法,每个方法都非常相似。
// 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;
}
如何使 setter class 中的 "boilerplate" 更通用?我不能像在上面的示例中那样使用特征,因为我不能将静态函数与对象联系起来。那么有没有办法让样板示例更常见?
某处有一个选择器,比如说
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(..);
}
理想情况下,我想将上面的 class 修改为
// Inside setter class further above
int get_thing_a()
{
return perform_action<THINGA>(...);
}
int get_thing_b()
{
return perform_action<THINGB>(...);
}
答案是,也许我不能,我需要将 shared_ptr 作为参数传递给 int 并调用我需要的特定方法,而不是尝试将 shared_ptr 方法绑定到一个静态函数(事后看来,这听起来不是个好主意……但我想反驳我的想法)
无论谁进行实际调用,都需要对象的引用,无论是哪种方式。因此,假设您希望 perform_action
执行实际调用,则必须传递参数。
现在,如果您真的想存储 Base
的哪个函数作为 static
在 thing_traits
中调用而不传递参数,您可以利用指向成员函数的指针:
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)() + ...;
}
您也可以尝试返回一个为您执行调用的函数对象(并且内部函数接受参数)。
这完全取决于您需要拨打电话的人以及您认为每个 class/template 可用的 information/dependencies。
从历史上看,我一直使用特征 classes 来保存信息并将其应用到运行相同 "algorithm." 的 "generic" 函数中,只是特征 [=48] 不同=].例如:https://onlinegdb.com/ryUo7WRmN
enum selector { SELECTOR1, SELECTOR2, SELECTOR3, };
// declaration
template < selector T> struct example_trait;
template<> struct example_trait<SELECTOR1> {
static constexpr size_t member_var = 3;
static size_t do_something() { return 0; }
};
template<> struct example_trait<SELECTOR2> {
static constexpr size_t member_var = 5;
static size_t do_something() { return 0; }
};
// pretend this is doing something useful but common
template < selector T, typename TT = example_trait<T> >
void function() {
std::cout << TT::member_var << std::endl;
std::cout << TT::do_something() << std::endl;
}
int main()
{
function<SELECTOR1>();
function<SELECTOR2>();
return 0;
}
在处理多态 classes 时,我不确定如何创建 "generic" 算法。
例如:https://onlinegdb.com/S1hFLGC7V
下面我创建了一个继承的 class 层次结构。在此示例中,我有一个基本的包罗万象的示例,它将所有参数默认为某个值(在本例中为 0)。然后每个派生 class 集覆盖特定方法。
#include <iostream>
#include <memory>
#include <type_traits>
#include <assert.h>
using namespace std;
struct Base {
virtual int get_thing_one() {
return 0;
}
virtual int get_thing_two() {
return 0;
}
virtual int get_thing_three() {
return 0;
}
virtual int get_thing_four() {
return 0;
}
};
struct A : public Base {
virtual int get_thing_one() override {
return 1;
}
virtual int get_thing_three() override {
return 3;
}
};
struct B : public Base {
virtual int get_thing_one() override {
return 2;
}
virtual int get_thing_four() override{
return 4;
}
};
这里我创建了一个简单的工厂,虽然不够优雅,但仅供说明之用
// 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 的兴趣所在。它是 class 对上面 classes 中的数据执行 "something"。下面的方法是一个简单的加法示例,但想象一个更复杂的算法,每个方法都非常相似。
// 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;
}
如何使 setter class 中的 "boilerplate" 更通用?我不能像在上面的示例中那样使用特征,因为我不能将静态函数与对象联系起来。那么有没有办法让样板示例更常见?
某处有一个选择器,比如说
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(..);
}
理想情况下,我想将上面的 class 修改为
// Inside setter class further above
int get_thing_a()
{
return perform_action<THINGA>(...);
}
int get_thing_b()
{
return perform_action<THINGB>(...);
}
答案是,也许我不能,我需要将 shared_ptr 作为参数传递给 int 并调用我需要的特定方法,而不是尝试将 shared_ptr 方法绑定到一个静态函数(事后看来,这听起来不是个好主意……但我想反驳我的想法)
无论谁进行实际调用,都需要对象的引用,无论是哪种方式。因此,假设您希望 perform_action
执行实际调用,则必须传递参数。
现在,如果您真的想存储 Base
的哪个函数作为 static
在 thing_traits
中调用而不传递参数,您可以利用指向成员函数的指针:
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)() + ...;
}
您也可以尝试返回一个为您执行调用的函数对象(并且内部函数接受参数)。
这完全取决于您需要拨打电话的人以及您认为每个 class/template 可用的 information/dependencies。