传递函数签名时C模板不编译

前端之家收集整理的这篇文章主要介绍了传递函数签名时C模板不编译前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
考虑以下最小的例子(没有#1和#2编译):
void foo(void)
{ }

template<typename T> class Stage2;

template<typename Ret,typename... Args>
struct Stage2<Ret (Args...)>
{
    template<Ret (*func)(Args...)>
    static void foobar(void)
    { /* Do something */ }
};

template<typename FuncType>
struct Stage1
{
    template<FuncType func>
    static void bar(void)
    {
        Stage2<FuncType>::foobar<func>();       // #1,Not working
        Stage2<decltype(func)>::foobar<func>(); // #2,Not working
        Stage2<void()>::foobar<func>();         // #3,Working
    }
};

int main(void)
{
    Stage1<decltype(foo)>::bar<foo>();
    return 0;
}

为什么它不能用#1和#2编译,而它用#3编译得很好?在我看来,只要foo具有签名void(),#3就应该等同于其他的,在本例中它就是这样.即使编译器告诉我,FuncType实际上也是void()(见下文).

错误消息(#1和#2相同):

main.cpp: In static member function ‘static void Stage1<FuncType>::bar()’:
main.cpp:21:40: error: expected primary-expression before ‘)’ token
         Stage2<FuncType>::foobar<func>();       // #1,Not working
                                        ^
main.cpp: In instantiation of ‘static void Stage1<FuncType>::bar() [with FuncType func = foo; FuncType = void()]’:
main.cpp:29:37:   required from here
main.cpp:21:33: error: invalid operands of types ‘<unresolved overloaded function type>’ and ‘void (*)()’ to binary ‘operator<’
         Stage2<FuncType>::foobar<func>();       // #1,Not working
         ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~

我在这里想念的是什么?我用的是7.2.0.

注意:如果这对任何方式都有用,我真的不感兴趣,我只想知道它为什么不编译,因为它对我没用.

解决方法

基本上,这是怎么回事:
Stage2<FuncType>::foobar<func>();

包含一个从属名称(取决于FuncType),因此您必须遵循正确的C -Syntax调用成员模板(因此语法错误消息),这是

Stage2<FuncType>::template foobar<func>();

请注意,这不适用于Stage2< void()> :: foobar< func>();因为没有涉及的附属名称.

这同样适用于Stage2< decltype(func)> :: foobar< func>();,但是这仍然无法修复它,因为存在一些棘手的障碍.根据§14.1.8[temp.param],

A non-type template-parameter of type “array of T” or “function returning T” is adjusted to be of type “pointer to T” or “pointer to function returning T”,respectively.

decltype(func)将为void(*)()而不是void()(即使FuncType被指定为void()),因此没有函数类型,但指向函数类型的指针将作为模板参数传递给Stage2,没有提供专业化(因为Stage2< Ret(Args ...)>和Stage2< Ret(*)(Args ...)>不一样),因此回退到默认模板声明,最后产生一个“使用不完整类型”错误.

猜你在找的C&C++相关文章