我正在探索两种方法将函数传递给类模板Bar
的ctor,如下所示online。
测试的编译器:GCC 5.4.0和clang 3.8.0。 (在线版本中禁用了违规构造。)
#include <iostream>
#include <cxxabi.h>
#define DEMANGLE( object ) \
{ \
int status; \
char* name = abi::__cxa_demangle( typeid( object ).name() , 0 , 0 , &status ); \
if( !status ) std::cout << name << std::endl; \
delete name; \
}
template<typename T>
struct Bar;
template<typename ...Args>
struct Bar<void(Args...)>
{
#if 0
Bar( void(Args...) ) // OKAY
{ // Question 1: need to assign a name to the function void(Args...)
}
#else
Bar( void(Args...) func ) // ERROR
{
}
#endif
};
void wiggle( bool , short , int )
{
}
template<typename F>
void wrapper( F f )
{
//DEMANGLE( f ) // optional print out of the type of F
Bar<F> bar( f ) ; // Question 2: incomplete type error -- why is specialization of Bar not chosen???
}
int main()
{
wrapper( wiggle );
Bar<decltype(wiggle)> f( &wiggle );
}
问题1
我首次尝试将函数wiggle
传递给Bar
是直接将后者实例化为Bar<decltype(wiggle)> f( &wiggle )
。问题是如何命名/引用传递给构造函数Bar::Bar(f)
的函数。使用未命名的参数Bar( void(Args...) )
编写ctor编译好,但是当我尝试命名或引用传递给ctor的参数时,如Bar( void(Args...) func )
,我得到编译器错误
source_file.cpp:23:21: error: expected ')'
Bar( void(Args...) func ) // ERROR
^
source_file.cpp:23:5: note: to match this '('
Bar( void(Args...) func ) // ERROR
问题2
我第二次尝试将函数传递给Bar
,使用函数void wrapper( F f )
来调用Bar<F> bar( f )
。奇怪的是,两个编译器都达到Bar
的(未实现的)基本模板而不是专门化,这会产生错误
source_file.cpp:37:9: error: implicit instantiation of undefined template 'Bar<void (*)(bool, short, int)>'
Bar<F> bar( f );
^
source_file.cpp:42:2: note: in instantiation of function template specialization 'wrapper<void (*)(bool, short, int)>' requested here
wrapper( wiggle );
^
source_file.cpp:13:8: note: template is declared here
struct Bar;
特别令人困惑的是,类型名称信息转储宏DEMANGLE
确认传递给F
的{{1}}类型为wrapper
。
答案 0 :(得分:2)
问题是wiggle
在传递给wrapper
时被隐式转换为函数指针,因此F
的实际类型是:
void (*)(bool, short, int)
...与void(Args)
无法匹配。您可以使用std::remove_pointer_t
:
Bar<std::remove_pointer_t<F>> bar( f );
关于您的第一个错误,Bar(void (Args...) func)
不是正确的构造,Bar(void func(Args...))
会在这里,但是that would be equivalent to:
Bar(void (*func)(Args...))
......更清楚(在我看来)。