C++ 내부 클래스에 대해 질문입니다.

hsnks100의 이미지

#include <vector>
#include <algorithm>
 
using namespace std;
int main()
{
	vector<int> v;
 
	struct Functor
	{
		void operator()(int e)
		{
			e;
		}
	}functor;
	for_each(v.begin(), v.end(), functor);
	return 0;
}

이러한 코드가 vs2010 에서는 문제없이 동작하는데 gcc 4.6.1 에서는 다음과 같은 에러를 뿜습니다.

test.cpp: In function 'int main()':
test.cpp:16:38: error: no matching function for call to 'for_each(std::vector t>::iterator, std::vector::iterator, main()::Functor&)'
test.cpp:16:38: note: candidate is:
c:\mingw\bin\../lib/gcc/mingw32/4.6.1/include/c++/bits/stl_algo.h:4296:74: note:
template _Funct std::for_each(_IIter, _IIter, _Func
t)

main()::Functor 의 타입을 인자로 받는데요. 어차피 template 으로 선언되어있는데 왜 매칭을 못하는걸까요? 이해가 안되네요.

익명 사용자의 이미지

차기 표준이면 모를까 현 표준에선 위와 같은 코드는 불가능합니다.(되는게 비표준이죠...)
위에 에러메세지 보시면 main()::Functor& 타입이 등장하는데...
로컬 클래스의 경우 linkage가 없기 때문에 템플릿 인자로 사용될 수 없습니다.

결국은 boost의 lambda를 사용하시거나, 해당 컴파일러가 차기 표준(중 해당부분)이 지원되는지 확인하시고 해당 표준으로 컴파일 해보시기 바랍니다.

표준에서도 템플릿 항목에서 해당 부분에 대해 설명하는걸 예제로 한두개 봣던 기역이 있네요.

hsnks100의 이미지

고맙습니다. 근데 지역 클래스 스코프를 쓸 수 없는 이유가 뭔가요? linkage 가 없기 때문에 -> linkage 가 없는 이유가 뭔가요?

왜 그렇죠?? ㅜㅜ 안되게 만들어논 이유가 있을텐데... linkage 로 다 설명이 되나요? .. 소인의 눈엔 되게 만들어도 아무런 ㅇ문제가 없을거 같은데

----------------------------------------------------
개인 블로그: https://kangssu.com

yielding의 이미지

14.3.1 Template type arguments
1 ....
2 A local type, a type with no linkage, an unnamed type or a type compounded from any of these types shall
not be used as a template-argument for a template type-parameter. [Example:

template <class T> class X { /* ... */ };
void f()
{
   struct S { /* ... */ };
   X<S> x1;        // error: local type used as template-argument
   X<S&> x2;      // error: pointer to local type used as ...
};

표준에서 금지한다고 기술적으로 구현 불가능한 것은 아니죠. 표준을 만들때야 어떤 이유로 이 문법이 채택되지 않았지만 (바빠서라든지 --;)
c++0x에서 lamda로 아주 깔끔하게 구현 가능한 지금 상황에서 유추해 본다면 당시에 실수한 것인 듯 합니다.

그런데 lamda를 쓸 수 있는 지금에와서 굳이 local class 쓸 일이 있나요?

int main(int argc, char const* argv[])
{
  vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  auto functor = [](int x) { .... }
  for_each(v.begin(), v.end(), functor);
  ...
}

Life rushes on, we are distracted

익명 사용자의 이미지

C++11 표준에서는 아무런 문제가 없는 소스코드입니다.
VC++ 2010에서 잘 컴파일 되는건 그게 그 표준을 기본으로 컴파일하기 때문이죠.

g++은 아직 C++03 표준을 기본으로 하고 있어서 오류 메시지가 나는 것인데
-std=c++0x 옵션을 주고 C++11 표준으로 컴파일하면 아무 문제 없습니다.

hsnks100의 이미지

감사합니다. 최신 표준엔 아무런 문제가 없는 코드군요.

우문현답 고맙습니다.

----------------------------------------------------
개인 블로그: https://kangssu.com

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.