如何确定函数的参数 type 是否为函数?我正在实现一个名为Queue
的类,该类接收单个参数。如果参数是函数,则存储该函数。
代码如下:
template <class Type, typename Data>
class Queue {
public:
void Enqueue (Data& data) {
if (typeid(data).name() == int) {
intVector.push_back(data);
order.push_back("int");
}
else if (typeid(data).name() == bool) {
boolVector.push_back(data);
order.push_back("bool");
}
else if (typeid().name() == string) {
stringVector.push_back(data);
order.push_back("string");
}
// This will continue for:
// - double
// - char
// - function
}
auto Dequeue () {
auto temp;
switch (order.begin()) {
case "int":
temp = intVector.begin();
intVector.erase(intVector.begin());
order.erase(order.begin());
return temp;
// This will continue for:
// - "string"
// - "bool"
// - "char"
// - "double"
// - "function"
default:
cout << "An Error occurred while trying to Enqueue." << endl;
cout << "\tAddress: " << this << endl;
}
}
auto Start () {
// This function will run all of the processes...
}
Queue (Data& data) {
if (typeid(Type).name() == int) {
// Pseodo-code:
// if (data.type == function) {
// Enqueue (data);
// }
}
}
}
可以初始化:
Queue queue1 = new Queue <int> (func ()); // func () is a function.
Queue queue2 = new Queue <int> (var); // var is a variable.
答案 0 :(得分:2)
哦,天哪。这有点XY problem。
无论如何,在与std::enable_if
纠缠了一段时间(这很有趣)之后,我意识到整个事情可以归结为:
#include <vector>
#include <string>
#include <any>
#include <iostream>
#include <functional>
void call_if_function (void (* f) ()) { f (); }
void call_if_function (std::function <void ()> f) { f (); }
void call_if_function (std::any x) { (void) x; }
template <class T>
class Queue
{
public:
void Enqueue (const T& data)
{
// std::cout << "Enqueueing " << data << "\n";
v.push_back (data);
}
T Dequeue ()
{
T ret = v.front ();
// std::cout << "Dequeueing " << ret << "\n";
v.erase (v.begin ());
call_if_function (ret);
return ret;
}
private:
std::vector <T> v;
};
而且,如果我正确理解OP的问题,那就是您所需要的全部。
测试程序:
void foo () { std::cout << "foo () called\n"; }
void bar (int x, int y) { std::cout << "bar () called, x = " << x << ", y = " << y << "\n"; }
int main ()
{
// Queue of int's
Queue <int> int_q;
int_q.Enqueue (42);
auto i = int_q.Dequeue ();
std::cout << "int_q.Dequeue () returned " << i << "\n\n";
// Queue of strings
Queue <std::string> string_q;
string_q.Enqueue ("Hello world");
auto s = string_q.Dequeue ();
std::cout << "string_q.Dequeue () returned " << s << "\n\n";
// Call function with no parameters
Queue <void (*)()> func_q;
func_q.Enqueue (foo);
auto f = func_q.Dequeue ();
std::cout << "func_q.Dequeue () returned " << (void *) f << "\n";
f ();
// Call function with arbitrary parameters
Queue <std::function <void ()>> func_qp;
func_qp.Enqueue ([] () { bar (21, 99); });
auto fp = func_qp.Dequeue ();
fp ();
}
输出:
int_q.Dequeue () returned 42
string_q.Dequeue () returned Hello world
foo () called
func_q.Dequeue () returned 0x4026fd
foo () called
bar () called, x = 21, y = 99
bar () called, x = 21, y = 99
道德:亲吻,这几天玩具箱里的玩具太多了。享受周末的人。
答案 1 :(得分:2)
而且,由于我花了一些时间来研究它(主要是因为我想学习一些有关它的知识),所以这里有一些来自the wise ones的非常简单的SFINAE。
#include <type_traits>
#include <iostream>
// Primary template (required)
template <class T, class Enable = void>
struct X { };
// Specialisation to take a function pointer
template <class T>
struct X <T, typename std::enable_if <std::is_function<T>::value>::type>
{
X (T func)
{
std::cout << "T is a function\n";
func ();
}
};
// Partial specialisation for anything else
template<class T>
struct X <T, typename std::enable_if <!std::is_function<T>::value>::type>
{
X (T x)
{
std::cout << "T is not a function (and x is " << x << ")\n";
}
};
void foo () { std::cout << "foo () called\n"; }
int main ()
{
X <void ()> x1 (foo);
X <int> x2 (42);
}
输出:
T is a function
foo () called
T is not a function (and x is 42)
功能强大,但不能解决所有小问题。
答案 2 :(得分:1)
如何确定函数的参数类型是否为函数?
您可以使用std::is_function
来做到这一点。
类似于
的实现frame_data = pd.read_csv('final results.csv', header=[0,1])
frame_data[('exp', 'Mean')] = frame_data.iloc[:, -3:].mean(axis=1)
#flatten MultiIndex to columns
frame_data.columns = frame_data.columns.map('_'.join)
grouped_by_group = frame_data.groupby('8_Group')['exp_Mean'].mean()
print (grouped_by_group)
8_Group
0.1 72.150000
1 92.433333
HD 0 88.966667
WT 0 71.519048
Name: value, dtype: float64
grouped_by_group.plot.bar(title='Grip')
但是不起作用,因为编译器会看到template <class Type, typename Data>
class Queue {
public:
Queue (Data& data) {
if (typeid(Type).name() == int) {
// Pseodo-code:
if (std::is_function<data.type>::value) {
Enqueue (data);
}
}
}
}
块作用域内的其他数据类型。
要意识到您将需要使用SFINAE,并使用std::enable_if
为if
构造函数提供不同的专业化。
答案 3 :(得分:-1)
对于SFINAE示例:
Queue(std::enable_if_t<std::is_function_v<Data>, Data>::type & data)
{
//data is a function
}
//I'm not sure if the enable_if is needed here, maybe you can just do Data& data
Queue(std::enable_if_t<!std::is_function_v<Data>, Data>::type & data)
{
//data is not a function
}
(您需要包括<type_traits>
才能使用std::is_function_v
)