如何通过引用和指针将参数传递给函数。我有一个示例,其中我尝试调用 CFoo 类的两个写入函数之一。如果您指定两个用逗号分隔的“参数包” const Args1... a, const Args0... b,则该示例将编译,但如果您指定调用 OnFoo(&CFoo::write, ....);,则它仅适用于两种情况之一。如果你交换“参数包”const Args1 ... a,const Args0 ... b,那么图片将完全相反,另一个调用将起作用。如何使这两个调用都工作或将两个“参数包”替换为一个,以便您可以通过引用和指针传递参数?
class CFoo
{
public:
static void write(const char& a, const char& b, const char& c)
{
}
static void write(const char* a, const char* b, const char* c)
{
}
};
#define TYPE_FUNCTION const Args1*... a, const Args0&... b // Work for call with reference
// #define TYPE_FUNCTION const Args0&... a, const Args1*... b // Work for call with point
template <class... Args0, class... Args1> void OnFoo(void (*func)(TYPE_FUNCTION), TYPE_FUNCTION)
{
}
int main(int argc, char** argv)
{
OnFoo(&CFoo::write, '1', '1', '1');
// OnFoo(&CFoo::write, "1", "1", "1");
return 0;
}
//第一种情况
class CFoo
{
public:
static void write(const char& a, const char& b, const char& c)
{
}
static void write(const char* a, const char* b, const char* c)
{
}
};
#define TYPE_FUNCTION const Args1*... a, const Args0&... b // Work for call with reference
template <class... Args0, class... Args1> void OnFoo(void (*func)(TYPE_FUNCTION), TYPE_FUNCTION)
{
}
int main(int argc, char** argv)
{
OnFoo(&CFoo::write, '1', '1', '1');
OnFoo(&CFoo::write, "1", "1", "1"); // Error
return 0;
}
错误:
main.cpp: In function 'int main(int, char**)':
main.cpp:24:38: error: no matching function for call to 'OnFoo(<unresolved overloaded function type>, const char [2], const char [2], const char [2])'
24 | OnFoo(&CFoo::write, "1", "1", "1");
| ^
main.cpp:17:48: note: candidate: 'template<class ... Args0, class ... Args1> void OnFoo(void (*)(const Args1* ..., const Args0& ...), const Args1* ..., const Args0& ...)'
17 | template <class... Args0, class... Args1> void OnFoo(void (*func)(TYPE_FUNCTION), TYPE_FUNCTION)
| ^~~~~
main.cpp:17:48: note: template argument deduction/substitution failed:
main.cpp:24:38: note: mismatched types 'const Args0&' and 'const char*'
24 | OnFoo(&CFoo::write, "1", "1", "1");
| ^
main.cpp:24:38: note: inconsistent parameter pack deduction with 'char' and 'char [2]'
//第二种情况
class CFoo
{
public:
static void write(const char& a, const char& b, const char& c)
{
}
static void write(const char* a, const char* b, const char* c)
{
}
};
#define TYPE_FUNCTION const Args1&... a, const Args0*... b // Work for call with reference
template <class... Args0, class... Args1> void OnFoo(void (*func)(TYPE_FUNCTION), TYPE_FUNCTION)
{
}
int main(int argc, char** argv)
{
OnFoo(&CFoo::write, '1', '1', '1'); // Error
OnFoo(&CFoo::write, "1", "1", "1");
return 0;
}
错误:
main.cpp:23:42: error: no matching function for call to 'OnFoo(<unresolved overloaded function type>, char, char, char)'
23 | OnFoo(&CFoo::write, '1', '1', '1');
| ^
main.cpp:17:52: note: candidate: 'template<class ... Args0, class ... Args1> void OnFoo(void (*)(const Args1& ..., const Args0* ...), const Args1& ..., const Args0* ...)'
17 | template <class... Args0, class... Args1> void OnFoo(void (*func)(TYPE_FUNCTION), TYPE_FUNCTION)
| ^~~~~
main.cpp:17:52: note: template argument deduction/substitution failed:
main.cpp:23:42: note: mismatched types 'const Args0*' and 'const char&'
23 | OnFoo(&CFoo::write, '1', '1', '1');
| ^
main.cpp:23:42: note: mismatched types 'const Args0*' and 'char'
第一种情况和第二种情况的区别在于我交换了通过引用和指针传递的“参数包”
您不能将重载集作为参数传递。
所以函数参数应该是不可推导的,
那么你可能会有函数参数,具体取决于其他参数,例如:
template <class... Args>
void OnFoo(std::conditional_t<(std::is_pointer_v<std::decay_t<Args>> && ...),
void(*)(std::decay_t<Args>...),
void(*)(const Args&...)>,
Args&&...)
{
// ...
}
您可以使用
ARGS
的类型信息执行以下操作,以便找到 CFoo::write
的相应重载版本:
#include <iostream>
class CFoo
{
public:
static void write (char a, char b, char c)
{
std::cout << "version1: " << a << " " << b << " " << c << "\n";
}
static void write (const char* a, const char* b, const char* c)
{
std::cout << "version2: " << a << " " << b << " " << c << "\n";
}
};
template <typename...ARGS>
void OnFoo (void (*fct)(ARGS...), ARGS...args)
{
fct (args...);
}
int main (int argc, char** argv)
{
OnFoo (&CFoo::write, '1', '2', '3' );
OnFoo (&CFoo::write, "11", "22", "33");
return 0;
}