检查传递给模板的函数在参数中有 class
check function passed to template has class in arguments
这有点难以解释,
在我的 class 中,我有一个带有指针和参数的创建函数
我希望能够检查传递给该函数的函数是否将 ClassPointer 作为其第一个参数,如果是这样,则自动将其添加到 "create" 内的函数中,如果不只是添加普通函数参数,就像我做的那样
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);
我相信 std::is_same 可能对您有用,正如上一个问题
问题可以更一般化。您可以询问如何确定函数的第 N 个参数是否属于给定类型。要静态获得此问题的答案,您可以创建 SFINAE 辅助结构 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
这有点难以解释, 在我的 class 中,我有一个带有指针和参数的创建函数 我希望能够检查传递给该函数的函数是否将 ClassPointer 作为其第一个参数,如果是这样,则自动将其添加到 "create" 内的函数中,如果不只是添加普通函数参数,就像我做的那样
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);
我相信 std::is_same 可能对您有用,正如上一个问题
问题可以更一般化。您可以询问如何确定函数的第 N 个参数是否属于给定类型。要静态获得此问题的答案,您可以创建 SFINAE 辅助结构 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