클래스 템플릿의 멤버 함수 중, 매개변수에 ... 은 무슨 뜻인가요?

ikpil의 이미지

template <typename D, typename B>
class IsDerivedFrom
{
public:
	typedef D D_Type;
	typedef B B_Type;
private:	
	struct No{};
	struct Yes	{ No a[2]; };
 
	static Yes Checker( B* );
	static No Checker( ... );
public:
	static const bool value = ( sizeof( Checker( static_cast<D*>(0) ) ) == sizeof( Yes ) );		
};

... 은 무슨 뜻일까요?

lifthrasiir의 이미지

인자의 ...는 가변 인수 목록입니다. 이 경우 모든 종류의 인자가 매칭 가능합니다. 예를 들어 Checker(1, false, 3.0f, std::string("foo")) 같은 게 올바르단 얘기죠. 읽을 때는 #include <cstdarg> 같은 걸로 읽어 들이는데, type-safe하지 않으므로 C++에서는 안 쓰는 게 권장됩니다.

그러나 이 코드에서 ...는 그런 목적으로 쓰이는 건 아니고, overload resolution 과정을 통해 원하는 prototype을 얻기 위해 사용합니다. overload resolution 규칙에 의하면 (만약 B가 D의 base라면) static_cast<D*>(0)은 ...으로 지정된 가변 인자보다는 B*에 더 부합되므로 해당 prototype이 선택되고, 그 반환값의 타입은 Yes가 될 겁니다. 반대로 B가 D의 base가 아니라면 ...만이 candidate이므로 반환값 타입이 No가 되겠죠.

어렵지 않은(!) 코드니 잘 생각해 보시면 왜 동작하는지 아실 수 있을 것입니다. 뭐 메타 프로그래밍을 잘 익혀 봐야 겠다! 같은 생각을 가지고 계신 게 아니라 그냥 코드만 훑어 보시는 거라면 생략하는 게 더 낫겠지만요.

neogeo의 이미지

위의 내용은 가변인수를 나타내는 내용으로써 아마 주로 C 언어 교재에 그내용이 나와있을껍니다.

printf 함수등의 원형을 공부해보시면 쉽게 아실 수 있을겁니다.

또 반드시 va_list 등의 사용법이나 매크로를 익혀두시길 권합니다. ( C++ 할때는 별로 필요는 없겠지만, 서버 프로그래밍 할때나 뭔가 알고리즘을 사용하기 쉽게 확장하고플때 사용하실필요가 있을지도 모릅니다. )

Neogeo - Future is Now.

Neogeo - Future is Now.

ikpil의 이미지

우선 관심 가져 주신 두분에게 감사합니다.

이 코드를 보는 중에 또 다시 궁금증이 생겼습니다.
Checker의 경우, 함수의 본체가 없음에도 static const bool value = ( sizeof( Checker( static_cast(0) ) ) == sizeof( Yes ) ); 이 부분이 잘 돌아 가는 것을 볼 수 있는데,
본체가 실행되지도 않았는데, 어떻게 ... sizeof() 가 정상적으로 호출 될 수 있는지 굼긍합니다.

winner의 이미지

사긴 했는데 읽지도 않고 처박아놨던 Morder C++ Design을 꺼내들고 둘러봤습니다만 동일한 code는 안나오네요.
C++ Templates나 C++ Template Metaprogramming에나 나올법한 code인데...

sizeof는 compile time에 모든 연산이 이루어집니다. Runtime 형 크기를 구하는 것이 아니기 때문에
결과값 자체는 compile time에 구할 수 있죠.
위와 같이 함수의 반환형의 경우 함수의 부작용으로 인해 실제 함수호출이 이루어져야 하는 것은 아닌가 했습니다만
sizeof 자체가 compile time에 이루어져야 하므로 그런 일은 발생하지가 않는 것 같군요.

아마도 함수의 반환형에 sizeof 연산을 적용하기 위하여 예외를 적용했나 보네요.

참고로 C++ 차기표준에는 아예 result_of 라고 해서 함수반환형을 구할 수 있게 되었습니다.

ikpil의 이미지

설명 자체가 감동입니다. 더욱 정진하겠습니다.

winner의 이미지

공부 좋아하시네요. 부럽습니다.
요새 이것 저것 혼란스러운게...
오늘 아침 미스터 소크라테스가 하던데 저는 지금 주변인, 제 2의 탄생기인 것 같군요.

winner의 이미지

저는 C와 C++를 가지고 고민하게 오래 되어서 잊고 있었는데
마찬가지로 사놓고 처박아둔 'C언어 펀더멘탈'을 보면

sizeof는 '수식은 직접 평가되지 않고 데이터형만으로 결과값이 생성된다'
, '피연산자로 주어진 수식에 부작용이 있어도 절대 일어나지 않는다.'
고 합니다.

하지만 정의되지 않은 함수의 호출에 대해서는 안 나와 있긴 한데...

C표준에 의하면 다음과 같습니다.

If an identifier declared with external
linkage is used in an expression (other than as part of the operand of a sizeof operator
whose result is an integer constant), somewhere in the entire program there shall be
exactly one external definition for the identifier; otherwise, there shall be no more than
one.)

해석은 직접.... ^_^

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.