这有点难以解释, 在我的类中,我有一个带有指针和参数的create函数 我希望能够检查传递给该函数的函数是否具有ClassPointer作为其第一个参数,如果这样自动将其添加到函数内部" create"如果不是只是添加正常的函数参数(如果有的话),比如im doing
template <typename Function, typename... Arguments>
void SomeClass::create(HWND hWnd, Function func, Arguments&&... args)
{
// check if function's 1st argument = class pointer
std::function<void()> function = std::function<void()>(std::bind(std::forward<Function>(func), this, std::forward<Arguments>(args)...));
// else
std::function<void()> function = std::function<void()>(std::bind(std::forward<Function>(func), std::forward<Arguments>(args)...));
}
void ThreadProc1(SomeClass* pThis, HWND hwnd)
{
// do some stuff in here
}
void ThreadProc2(HWND hwnd)
{
// do some stuff in here
}
test.Create(hwnd, ThreadProc1, hwnd);
test.Create(hwnd, ThreadProc2, hwnd);
答案 0 :(得分:1)
问题可以更加普遍。您可以询问如何确定函数的第N个参数是否属于给定类型。要在这个问题上静态获得答案,您可以创建SFINAE helper struct nth_param_is,如下所示:
#include <type_traits>
#include <functional>
#include <iostream>
using namespace std;
typedef int HWND;
template<int N, class T, class... Args>
struct nth_template_param_is: false_type { };
template<int N, class T, class First, class... Others>
struct nth_template_param_is<N, T, First, Others...>: nth_template_param_is<N-1, T, Others...> { };
template<class T, class First, class... Others>
struct nth_template_param_is<0, T, First, Others...>: is_same<T, First> { };
template<int N, class T, class Foo>
struct nth_param_is: false_type {};
template<int N, class T, class Result, class... Args>
struct nth_param_is<N, T, Result(*)(Args...)>: nth_template_param_is<N, T, Args...> { };
struct SomeClass {
template <typename Function, typename... Arguments>
typename enable_if<nth_param_is<0, SomeClass *, Function>::value >::type create(HWND hWnd, Function func, Arguments&&... args)
{
// check if function's 1st argument = class pointer
std::function<void()> function = std::function<void()>(std::bind(std::forward<Function>(func), this, std::forward<Arguments>(args)...));
cout << "function with 1st argument = class pointer" << endl;
function();
}
template <typename Function, typename... Arguments>
typename enable_if<!nth_param_is<0, SomeClass *, Function>::value >::type create(HWND hWnd, Function func, Arguments&&... args)
{
// else
cout << "function with 1st argument = non-class pointer" << endl;
std::function<void()> function = std::function<void()>(std::bind(std::forward<Function>(func), std::forward<Arguments>(args)...));
function();
}
};
void ThreadProc1(SomeClass* pThis, HWND hwnd)
{
cout << "ThreadProc1 invoked" << endl;
// do some stuff in here
}
void ThreadProc2(HWND hwnd)
{
cout << "ThreadProc2 invoked" << endl;
// do some stuff in here
}
int main() {
HWND hwnd;
SomeClass test;
test.create(hwnd, ThreadProc1, hwnd);
test.create(hwnd, ThreadProc2, hwnd);
}
修改强>
我在头文件之间移动了功能,一切正常 例如:
my_traits.h:
#ifndef MY_TRAITS_H
#define MY_TRAITS_H
#include <type_traits>
template<int N, class T, class... Args>
struct nth_template_param_is: std::false_type { };
template<int N, class T, class First, class... Others>
struct nth_template_param_is<N, T, First, Others...>: nth_template_param_is<N-1, T, Others...> { };
template<class T, class First, class... Others>
struct nth_template_param_is<0, T, First, Others...>: std::is_same<T, First> { };
template<int N, class T, class Foo>
struct nth_param_is: std::false_type {};
template<int N, class T, class Result, class... Args>
struct nth_param_is<N, T, Result(*)(Args...)>: nth_template_param_is<N, T, Args...> { };
#endif
some_class.h:
#ifndef SOME_CLASS_H
#define SOME_CLASS_H
#include <type_traits>
#include <iostream>
#include <functional>
#include "my_traits.h"
typedef int HWND;
struct SomeClass {
// check if function's 1st argument = class pointer
template <typename Function, typename... Arguments>
typename std::enable_if<nth_param_is<0, SomeClass *, Function>::value >::type create(HWND hWnd, Function func, Arguments&&... args) {
std::function<void()> function = std::function<void()>(std::bind(std::forward<Function>(func), this, std::forward<Arguments>(args)...));
std::cout << "function with 1st argument = class pointer" << std::endl;
function();
}
template <typename Function, typename... Arguments>
typename std::enable_if<!nth_param_is<0, SomeClass *, Function>::value >::type create(HWND hWnd, Function func, Arguments&&... args) {
std::cout << "function with 1st argument = non-class pointer" << std::endl;
std::function<void()> function = std::function<void()>(std::bind(std::forward<Function>(func), std::forward<Arguments>(args)...));
function();
}
};
#endif
usage.cc:
#include <iostream>
#include "some_class.h"
void ThreadProc1(SomeClass* pThis, HWND hwnd) {
std::cout << "ThreadProc1 invoked" << std::endl;
// do some stuff in here
}
void ThreadProc2(HWND hwnd) {
std::cout << "ThreadProc2 invoked" << std::endl;
// do some stuff in here
}
void ThreadProc3(SomeClass* pThis, int arg1, int arg2) {
std::cout << "ThreadProc3 invoked" << std::endl;
// do some stuff in here
}
int main() {
HWND hwnd;
SomeClass test;
test.create(hwnd, ThreadProc1, hwnd);
test.create(hwnd, ThreadProc2, hwnd);
test.create(hwnd, ThreadProc3, 1, 2);
}
汇编:
g++ -std=c++11 usage.cc
用法:
./a.out
输出:
function with 1st argument = class pointer
ThreadProc1 invoked
function with 1st argument = non-class pointer
ThreadProc2 invoked
function with 1st argument = class pointer
ThreadProc3 invoked
答案 1 :(得分:0)
我相信std :: is_same可能对你有用https://jsfiddle.net/pz1yd11u/1/