std::bind 인자 갯수에 대해 질문이 있습니다.

lee3390의 이미지

class ClassInfo
{
public:
	ClassInfo() : nID(0) {}
	~ClassInfo() {}
 
	bool GetInfo1(int nVal1, int& nOutVal1, std::string& strOut1, std::string& strOut2 )
	{
		nOutVal1 = nID;
		strOut1 = "out1";
		strOut2 = "out2";
		return true;
	}
	bool GetInfo2(int nVal1, int& nOutVal1, std::string& strOut1, std::string& strOut2, std::string& strOut3 )
	{
		nOutVal1 = nID;
		strOut1 = "out1";
		strOut2 = "out2";
		strOut3 = "out3";
		return true;
	}
 
	int nID;
};
 
int main()
{
	std::shared_ptr<ClassInfo> spInfo = std::make_shared<ClassInfo>();
	spInfo->nID = 10;
 
	int nVal1 = 5;
	int nOutVal1;
	std::string strOut1;
	std::string strOut2;
	std::string strOut3;
 
	auto _func1 = std::bind(&ClassInfo::GetInfo1, spInfo, nVal1, std::ref(nOutVal1), std::ref(strOut1), std::ref(strOut2));
	_func1();
 
	auto _func2 = std::bind(&ClassInfo::GetInfo2, spInfo, nVal1, std::ref(nOutVal1), std::ref(strOut1), std::ref(strOut2), std::ref(strOut3));
	_func2();
}


이러한 코드에서

auto _func1 = std::bind(&ClassInfo::GetInfo1, spInfo, nVal1, std::ref(nOutVal1), std::ref(strOut1), std::ref(strOut2));
_func1();

이 코드는 정상 컴파일이 되나

auto _func2 = std::bind(&ClassInfo::GetInfo2, spInfo, nVal1, std::ref(nOutVal1), std::ref(strOut1), std::ref(strOut2), std::ref(strOut3));
_func2();

이 코드는 컴파일 오류가 나고 있습니다.
왜 에러가 나오는지 모르겠네요
도움 부탁드리겠습니다.

< 내용 추가 > 컴파일러는 visual studio 2012 컴파일러 입니다. 에러는

error C2780: 'enable_if::value,std::_Bind,_Vx0_t,_Vx1_t,_Vx2_t,_Vx3_t,_Vx4_t>>::type std::bind(_Rx (__cdecl _Farg0::* const )(_V0_t,_V1_t,_V2_t,_V3_t,_V4_t) volatile const,_Vx0_t &&,_Vx1_t &&,_Vx2_t &&,_Vx3_t &&,_Vx4_t &&)' : 인수가 6개 있어야 하는데 7개를 사용했습니다.
1> C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\functional(1519) : 'std::bind' 선언을 참조하십시오.

이러한 에러가 100개가 넘게 출력되고 있습니다.

twinwings의 이미지

에러 코드도 없고,

ClassFu::GetUserProfileInfo2()

함수의 프로토타입도 없네요.

그리고, ClassFu::GetUserProfileInfo2()가 overrideing 되어 있지 않는한

_func1() _func2() 둘 중 하나만 binding 가능해 보입니다.

없던 argument를 만들 순 없으니까요

lee3390의 이미지

ClassFu::GetUserProfileInfo, ClassFu::GetUserProfileInfo2 가 아닌

ClassInfo::GetInfo1, ClassInfo::GetInfo2 입니다. 글은 수정해놓았습니다.

익명 사용자의 이미지

어떤 컴파일러의 어떤 버전으로 어떤 옵션을 주고 컴파일하셨고, 어떤 에러 메시지가 나왔나요?

GCC 5.3는 경고 메시지를 내긴 하지만 성공적으로 컴파일을 마칩니다: http://melpon.org/wandbox/permlink/DyJ6bgmgek2xjgMX 경고 메시지는 두 멤버 함수가 첫 번째 형식 인자 nVal1를 사용하지 않는다는 점을 지적합니다. 비효율적일 수 있음을 경고하지만 위험해 보이지는 않습니다.

lee3390의 이미지

컴파일러는 visual studio 2012 컴파일러 입니다.
에러는

error C2780: 'enable_if::value,std::_Bind,_Vx0_t,_Vx1_t,_Vx2_t,_Vx3_t,_Vx4_t>>::type std::bind(_Rx (__cdecl _Farg0::* const )(_V0_t,_V1_t,_V2_t,_V3_t,_V4_t) volatile const,_Vx0_t &&,_Vx1_t &&,_Vx2_t &&,_Vx3_t &&,_Vx4_t &&)' : 인수가 6개 있어야 하는데 7개를 사용했습니다.
1> C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\functional(1519) : 'std::bind' 선언을 참조하십시오.

이러한 에러가 100개가 넘게 출력되고 있습니다.

lee3390의 이미지

visual studio 2012 에서 std::bind 가 argument 갯수 제한이 있나보네요
2015에서는 제대로 컴파일이 됩니다.
개발 환경이 2012라... boost를 사용하여 해결하였습니다.
감사합니다.

익명 사용자의 이미지

전처리기 상수 _VARIADIC_MAX를 6으로 증가시키면 될 겁니다. C++ 표준은 bind를 다음과 같은 형태로 선언하고 있습니다.

template <class F, class... Args>
/* unspecified */ bind(F&& f, Args&&... args);

template <class R, class F, class... Args>
/* unspecified */ bind(F&& f, Args&&... args);

따라서, bind를 제대로 구현하려면 C++11의 가변인자 템플릿(variadic template) 기능이 필요합니다. 그런데, 비주얼 스튜디오는 2013 버전부터 가변인자 템플릿을 지원합니다. 그 이전 버전에서는 임시방편으로 function parameter pack (예를 들어, 위의 Args&&... args 부분) 자리에 최대 _VARIADIC_MAX 개의 인자를 넘겨줄 수 있도록 함수들을 정의하고 있습니다. _VARIADIC_MAX는 5부터 10까지의 값을 가질 수 있으며, 내정값은 5입니다.

아니면, bind 대신 람다 함수를 쓰는 것도 고려해보세요.

auto _func2 = [spInfo, nVal1, &nOutVal1, &strOut1, &strOut2, &strOut3]() {
    return spInfo->GetInfo2(nVal1, nOutVal1, strOut1, strOut2, strOut3);
};
_func2();

실제로 테스트해보지는 못했습니다만, 람다 함수는 비주얼 스튜디어 2012에서도 잘 지원하는 것으로 알고 있습니다.

댓글 달기

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