当前位置:  开发笔记 > 编程语言 > 正文

为什么这是合法的,c ++ typedef func

如何解决《为什么这是合法的,c++typedeffunc》经验,为你挑选了2个好方法。

我是在msvc 2005中做到的.

typedef void (*cleanup_t)();

void func(cleanup_t clean)
{
    cleanup_t();
}

为什么编译?而不是给我一个警告?好吧,它给了我一个未引用的形式参数警告,但最初我做了这个当干净在一个类没有没有未引用的形式参数时,这个代码给我的问题.

什么是cleanup_t(); 真的在做什么,重点是什么?现在笑了,我尝试了int(),这也有效.



1> Michael Burr..:

我认为这是一个表达式,其值为cleanup_t类型的默认值.换句话说,一个表达式返回一个返回void的函数的NULL指针.

在C/C++中,没有副作用的表达式(这是 - 我认为)是有效的语句,就像你可以有一个语句一样:

1 + 2;

这不是语法错误,但有些编译器可能会发出警告.它们通常不会为返回NULL值的无副作用表达式发出警告,或者只是变量名称,因为这种类型的表达式通常在宏中用于调试目的(如assert()宏).

您可以将其视为调用该cleanup_t类型的默认构造函数.在C++中添加了类似于内置类型(或其类型的typedef)的默认类似构造函数的语法,以便模板可以将作为模板参数传入的类型的项设置为默认值,同时仍允许模板类型参数为非用户定义的类型.可能还有其他原因,但我相信这是其中之一.

就像是:

template 
class foo
{
    T myT;

    public:

    foo() {
        myT = T();
    };
};

typedef void (*cleanup_t)();


class bar
{
};


int not_quite_a_cleanup_t_func()
{
    return 1;
}


int main()
{
    foo intFoo;
    foo cleanup_t_foo;
    foo barFoo;

    // here I'm going to harp on one of the things I don't like about C++:
    //
    //  That so many things that look like function calls are not or that
    //  the parens cause subtle behavior changes.
    //
    //  I believe this is the reason this question was posted to 
    //  stackoverflow, so it's not too far off topic.
    //  
    //  Many of these things exist because of backwards compatibility with C or
    //  because they wanted to fit in new features without adding keywords or
    //  new reserved tokens or making the parser even more complex than it already
    //  is.  So there are probably good rationales for them.
    //
    //  But I find it confusing more often than not, and the fact that there
    //  might be a rationale for it doesn't mean I have to like it...

    cleanup_t cleanup1();    // declares a function named cleanup1 that returns a cleanup_t

    cleanup_t cleanup2 = cleanup_t();   // cleanup2 is a variable of type cleanup_t that 
                                        //  is default initialized

    cleanup_t* cleanup3 = new cleanup_t;    // cleanup3 is a pointer to type cleanup_t that 
                                            //  is initialized to point to memory that is 
                                            //  *not* initialized

    cleanup_t* cleanup4 = new cleanup_t();  // cleanup4 is a pointer to type cleanup_t that
                                            //  is initialized to point to memory that *is*
                                            //  initialized (using default intialization)

    cleanup2 = cleanup_t( not_quite_a_cleanup_t_func);  // explicit type conversion using functional notation

    cleanup_t();    // the OP's problem
    cleanup2();     // call the function pointed to by cleanup2
    (*cleanup2)();  // same thing

    class cleanup_class
    {
        cleanup_t cleanup5;

    public:
        cleanup_class() : 
            cleanup5() // class member default initialization
        { };
    };
}



2> Steve Jessop..:

它正在执行cleanup_t类型的默认初始值设定项,以创建该类型的临时值,然后从不实际使用该临时值.

它很像构造函数调用,"MyClass c = MyClass();"的"MyClass()"部分,除了指针到函数类型实际上没有构造函数.当然在我的代码片段中,"MyClass()"不一定会创建一个临时的,因为它是一个初始化表达式."MyClass().some_method();"中的"MyClass()" 也许是一个更接近的类比.

"int()"是另一种说"int(0)"的方式,这是另一种说"(int)0"的方式,这是另一种说"0"的方式.同样,它分配给一个临时的,如果是整个语句,那么临时是未使用的.

如果您在GCC上使用-Wall编译问题中的代码,则会收到警告"语句无效".执行此操作的人的代码可能意味着键入"clean();",不会产生该警告,因为它当然会产生调用该函数的效果.切换警告的另一个原因,并正确地修复它们;-)

推荐阅读
重庆制造漫画社
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有