저는 이것이 cleanup_t 유형에 대한 기본값으로 평가되는 표현식이라고 생각합니다. 즉, void를 반환하는 함수에 NULL 포인터를 반환하는 식입니다. - (이것이 내가 생각하는) C/C++, 부작용과 표현에서
는이 같은 진술 할 수처럼 유효 문은 다음과 같습니다 구문 오류가 아니다
1 + 2;
을하지만, 일부 컴파일러는 경고를 줄 수 있습니다. 이러한 유형의 표현식은 매크로 (assert() 매크로와 같은)를 디버깅 목적으로 자주 사용하기 때문에 NULL 값을 반환하는 부작용이없는 표현식에 대한 경고를 제공하지 않습니다.
cleanup_t
유형의 기본 생성자를 호출하는 것으로 생각할 수 있습니다. 기본 형식 (또는 typedef)에 대한이 기본 생성자와 유사한 구문을 C++에 추가하여 템플릿에서 템플릿 매개 변수로 전달 된 형식의 항목을 기본값으로 설정하면서 템플릿 형식 매개 변수를 기본 형식으로 설정할 수 있도록했습니다 비 사용자 정의 유형. 다른 이유가있을 수 있지만 그 중 하나라고 생각합니다. 같은
뭔가 :
template <class T>
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<int> intFoo;
foo<cleanup_t> cleanup_t_foo;
foo<bar> 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
{ };
};
}