c++ 模板化静态 class 带有函数指针的 const 数组
c++ templated static class with a const array of function pointers
所以我真的需要一个具有以下结构的 class,其中 class 是模板化的,arr
是一个函数指针数组,但我似乎无法理解找出正确的语法:
--myclass.h--
#include <vector>
template <typename T>
class MyClass {
typedef void (*fptr)(std::vector<T> data);
static void foo(std::vector<T> data);
static void bar(std::vector<T> data);
static void baz(std::vector<T> data);
static const fptr arr[3];
};
--myclass.cpp--
#include "myclass.h"
#include <vector>
template <typename T> void MyClass<T>::foo(std::vector<T> data) { ... }
template <typename T> void MyClass<T>::bar(std::vector<T> data) { ... }
template <typename T> void MyClass<T>::baz(std::vector<T> data) { ... }
template <typename T> MyClass<T>::fptr MyClass<T>::arr[3] = { &foo, &bar, &baz };
如果有帮助,我的最终目标是让第四个成员函数从数组中调用 foo
、bar
或 baz
,这样我就可以避免多个开销if-else 语句(我的实际实现有接近 50 个这样的函数)。有更好的方法吗?
fptr
声明为 const
,因此也定义它 const
。另外,因为Sort
是一个模板,所以需要typename
来引用MyClass<T>::fptr
。
template<typename T>
const typename MyClass<T>::fptr MyClass<T>::arr[] = { &foo, &bar, &baz };
旁注:您将无法将此定义或静态函数的定义放入源文件中,因为它们是模板。
此外,考虑使用 using
代替 typedef
,并使用 std::array
代替原始数组:
using fptr = void (*)(std::vector<T>);
static const std::array<fptr, 3> arr;
// [...]
template<typename T>
const std::array<typename MyClass<T>::fptr, 3> MyClass<T>::arr = { &foo, &bar, &baz };
Is there a better way to do this?
可能,但如果没有更多关于你想要做什么的细节,我不能说。
将整个 class 模板移动到 .hpp 文件中并使用与声明相同的签名初始化 arr
:
template <typename T>
class MyClass {
typedef void (*fptr)(std::vector<T> data);
static void foo(std::vector<T> data) {}
static void bar(std::vector<T> data) {}
static void baz(std::vector<T> data) {}
static const fptr arr[3];
};
template <typename T>
const typename MyClass<T>::fptr MyClass<T>::arr[] = { &foo, &bar, &baz };
您也可以直接定义arr
:
#include <iostream>
#include <vector>
#include <array>
template <typename T>
class MyClass {
typedef void (*fptr)(std::vector<T> data);
static void foo(std::vector<T> data) {
for(int i : data) std::cout << "foo " << i << "\n";
}
static void bar(std::vector<T> data) {
for(int i : data) std::cout << "bar " << i << "\n";
}
static void baz(std::vector<T> data) {
for(int i : data) std::cout << "baz " << i << "\n";
}
public:
static constexpr std::array<fptr,3> arr = { &foo, &bar, &baz };
};
int main() {
MyClass<int> a;
a.arr[0](std::vector<int>(1));
a.arr[1](std::vector<int>(2));
a.arr[2](std::vector<int>(3));
}
输出:
foo 0
bar 0
bar 0
baz 0
baz 0
baz 0
您可以使用 std::function
并将它们存储到向量中。这是我到目前为止的想法。
#include <exception>
#include <iostream>
#include <functional>
#include <vector>
template<typename T>
class MyClass {
private:
std::vector<std::function<void(std::vector<T>)>> myFuncs_;
public:
MyClass() = default;
void addFunc( std::function<void(std::vector<T>)> func ) {
myFuncs_.push_back(func);
}
void caller(unsigned idx, std::vector<T> v ) {
return myFuncs_.at(idx)( v );
}
static void foo(std::vector<T> data) {
std::cout << "foo() called:\n";
for (auto& d : data)
std::cout << d << " ";
std::cout << '\n';
}
static void bar(std::vector<T> data) {
std::cout << "bar() called:\n";
for (auto& d : data)
std::cout << d << " ";
std::cout << '\n';
}
};
int main() {
try {
MyClass<int> myClass;
std::vector<int> a{ 1,3,5,7,9 };
std::vector<int> b{ 2,4,6,8,10 };
std::function<void(std::vector<int>)> funcA = MyClass<int>::foo;
std::function<void(std::vector<int>)> funcB = MyClass<int>::bar;
myClass.addFunc( funcA );
myClass.addFunc( funcB );
myClass.caller(0, a);
myClass.caller(1, b);
} catch( std::runtime_error& e ) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
-输出-
MyClass::foo() was called:
1 3 5 7 9
MyClass::bar() was called:
2 4 6 8 10
不确定这是否正是您要查找的内容。在这个例子中,MyClass::caller(...)
有两个参数,一个是你想要的函数指针向量的索引,另一个是函数需要作为输入的参数或数据。
所以我真的需要一个具有以下结构的 class,其中 class 是模板化的,arr
是一个函数指针数组,但我似乎无法理解找出正确的语法:
--myclass.h--
#include <vector>
template <typename T>
class MyClass {
typedef void (*fptr)(std::vector<T> data);
static void foo(std::vector<T> data);
static void bar(std::vector<T> data);
static void baz(std::vector<T> data);
static const fptr arr[3];
};
--myclass.cpp--
#include "myclass.h"
#include <vector>
template <typename T> void MyClass<T>::foo(std::vector<T> data) { ... }
template <typename T> void MyClass<T>::bar(std::vector<T> data) { ... }
template <typename T> void MyClass<T>::baz(std::vector<T> data) { ... }
template <typename T> MyClass<T>::fptr MyClass<T>::arr[3] = { &foo, &bar, &baz };
如果有帮助,我的最终目标是让第四个成员函数从数组中调用 foo
、bar
或 baz
,这样我就可以避免多个开销if-else 语句(我的实际实现有接近 50 个这样的函数)。有更好的方法吗?
fptr
声明为 const
,因此也定义它 const
。另外,因为Sort
是一个模板,所以需要typename
来引用MyClass<T>::fptr
。
template<typename T>
const typename MyClass<T>::fptr MyClass<T>::arr[] = { &foo, &bar, &baz };
旁注:您将无法将此定义或静态函数的定义放入源文件中,因为它们是模板。
此外,考虑使用 using
代替 typedef
,并使用 std::array
代替原始数组:
using fptr = void (*)(std::vector<T>);
static const std::array<fptr, 3> arr;
// [...]
template<typename T>
const std::array<typename MyClass<T>::fptr, 3> MyClass<T>::arr = { &foo, &bar, &baz };
Is there a better way to do this?
可能,但如果没有更多关于你想要做什么的细节,我不能说。
将整个 class 模板移动到 .hpp 文件中并使用与声明相同的签名初始化 arr
:
template <typename T>
class MyClass {
typedef void (*fptr)(std::vector<T> data);
static void foo(std::vector<T> data) {}
static void bar(std::vector<T> data) {}
static void baz(std::vector<T> data) {}
static const fptr arr[3];
};
template <typename T>
const typename MyClass<T>::fptr MyClass<T>::arr[] = { &foo, &bar, &baz };
您也可以直接定义arr
:
#include <iostream>
#include <vector>
#include <array>
template <typename T>
class MyClass {
typedef void (*fptr)(std::vector<T> data);
static void foo(std::vector<T> data) {
for(int i : data) std::cout << "foo " << i << "\n";
}
static void bar(std::vector<T> data) {
for(int i : data) std::cout << "bar " << i << "\n";
}
static void baz(std::vector<T> data) {
for(int i : data) std::cout << "baz " << i << "\n";
}
public:
static constexpr std::array<fptr,3> arr = { &foo, &bar, &baz };
};
int main() {
MyClass<int> a;
a.arr[0](std::vector<int>(1));
a.arr[1](std::vector<int>(2));
a.arr[2](std::vector<int>(3));
}
输出:
foo 0
bar 0
bar 0
baz 0
baz 0
baz 0
您可以使用 std::function
并将它们存储到向量中。这是我到目前为止的想法。
#include <exception>
#include <iostream>
#include <functional>
#include <vector>
template<typename T>
class MyClass {
private:
std::vector<std::function<void(std::vector<T>)>> myFuncs_;
public:
MyClass() = default;
void addFunc( std::function<void(std::vector<T>)> func ) {
myFuncs_.push_back(func);
}
void caller(unsigned idx, std::vector<T> v ) {
return myFuncs_.at(idx)( v );
}
static void foo(std::vector<T> data) {
std::cout << "foo() called:\n";
for (auto& d : data)
std::cout << d << " ";
std::cout << '\n';
}
static void bar(std::vector<T> data) {
std::cout << "bar() called:\n";
for (auto& d : data)
std::cout << d << " ";
std::cout << '\n';
}
};
int main() {
try {
MyClass<int> myClass;
std::vector<int> a{ 1,3,5,7,9 };
std::vector<int> b{ 2,4,6,8,10 };
std::function<void(std::vector<int>)> funcA = MyClass<int>::foo;
std::function<void(std::vector<int>)> funcB = MyClass<int>::bar;
myClass.addFunc( funcA );
myClass.addFunc( funcB );
myClass.caller(0, a);
myClass.caller(1, b);
} catch( std::runtime_error& e ) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
-输出-
MyClass::foo() was called:
1 3 5 7 9
MyClass::bar() was called:
2 4 6 8 10
不确定这是否正是您要查找的内容。在这个例子中,MyClass::caller(...)
有两个参数,一个是你想要的函数指针向量的索引,另一个是函数需要作为输入的参数或数据。