2010-06-05 10 views
0

후속 : 나는 boost::format와 문자열의 형식을 람다를 사용하는 함수를 만드는 boost::function를 사용하기 위해 노력하고있어 Using * Width & Precision Specifiers With boost::format부스트 : : 기능 및 부스트 : : 람다 게시물에 다시

. 궁극적으로 무엇을 달성하기 위해 노력하고있다 형식으로 문자열에 대한 & 정밀도 지정자를 사용하고 있습니다. in the docs를 나타낸 바와 boost::format* 폭 & 정밀도 지시자의 사용을 지원하지 않습니다

폭 별표로 설정 정밀도 (*) 는 인수로부터이 분야 를 읽을의 printf 의해 사용된다. 예 : printf ("% 1 $ d : % 2 $. * 3 $ d : % 4 $. * 3 $ d \ n", 시, 분, 초, 초); 이 클래스 은 에 대해이 메커니즘을 지원하지 않습니다. 그러한 정밀도 또는 폭 필드 은 파싱에 의해 조용히 무시됩니다.

그래서 같은 목표를 달성 할 수있는 다른 방법을 찾기 위해 노력하고있어.

#include <string> 
#include <boost\function.hpp> 
#include <boost\lambda\lambda.hpp> 
#include <iostream> 
#include <boost\format.hpp> 
#include <iomanip> 
#include <boost\bind.hpp> 

int main() 
{ 
using namespace boost::lambda; 
using namespace std; 

boost::function<std::string(int, std::string)> f = 
    (boost::format("%s") % boost::io::group(setw(_1*2), setprecision(_2*2), _3)).str(); 

std::string s = (boost::format("%s") % f(15, "Hello")).str(); 

    return 0; 
} 

이 많은 컴파일러 오류를 생성합니다 : 부스트의 람다 및 기능

1>------ Build started: Project: hacks, Configuration: Debug x64 ------ 
1>Compiling... 
1>main.cpp 
1>.\main.cpp(15) : error C2872: '_1' : ambiguous symbol 
1>  could be 'D:\Program Files (x86)\boost\boost_1_42\boost/lambda/core.hpp(69) : boost::lambda::placeholder1_type &boost::lambda::`anonymous-namespace'::_1' 
1>  or  'D:\Program Files (x86)\boost\boost_1_42\boost/bind/placeholders.hpp(43) : boost::arg<I> `anonymous-namespace'::_1' 
1>  with 
1>  [ 
1>   I=1 
1>  ] 
1>.\main.cpp(15) : error C2664: 'std::setw' : cannot convert parameter 1 from 'boost::lambda::placeholder1_type' to 'std::streamsize' 
1>  No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called 
1>.\main.cpp(15) : error C2872: '_2' : ambiguous symbol 
1>  could be 'D:\Program Files (x86)\boost\boost_1_42\boost/lambda/core.hpp(70) : boost::lambda::placeholder2_type &boost::lambda::`anonymous-namespace'::_2' 
1>  or  'D:\Program Files (x86)\boost\boost_1_42\boost/bind/placeholders.hpp(44) : boost::arg<I> `anonymous-namespace'::_2' 
1>  with 
1>  [ 
1>   I=2 
1>  ] 
1>.\main.cpp(15) : error C2664: 'std::setprecision' : cannot convert parameter 1 from 'boost::lambda::placeholder2_type' to 'std::streamsize' 
1>  No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called 
1>.\main.cpp(15) : error C2872: '_3' : ambiguous symbol 
1>  could be 'D:\Program Files (x86)\boost\boost_1_42\boost/lambda/core.hpp(71) : boost::lambda::placeholder3_type &boost::lambda::`anonymous-namespace'::_3' 
1>  or  'D:\Program Files (x86)\boost\boost_1_42\boost/bind/placeholders.hpp(45) : boost::arg<I> `anonymous-namespace'::_3' 
1>  with 
1>  [ 
1>   I=3 
1>  ] 
1>.\main.cpp(15) : error C2660: 'boost::io::group' : function does not take 3 arguments 
1>.\main.cpp(15) : error C2228: left of '.str' must have class/struct/union 
1>Build log was saved at "file://c:\Users\john\Documents\Visual Studio 2005\Projects\hacks\x64\Debug\BuildLog.htm" 
1>hacks - 7 error(s), 0 warning(s) 
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== 

내 기본적인 이해는 아마 부족한 여기

내가 작동하지 않는, 지금까지 가지고있는 것입니다. 어떻게 작동시킬 수 있습니까?

답변

2

나는이 경우 boost.lambda 대신 boost.bind를 사용하려고한다고 생각한다. 문제의 일부는 boost :: io :: group은 가변 개수의 객체를 가져 와서 반환하는 함수 템플릿이므로 함수 <> 선언에 대한 적절한 서명을 만드는 것을 어렵게 만듭니다. 간단한 서명으로 문자열 서식 함수를 만든 다음 boost.bind를 사용하여 특정 서식 지정 함수 작성기를 작성합니다. 즉

#include <string> 
#include <iomanip> 
#include <boost/function.hpp> 
#include <boost/format.hpp> 
#include <boost/bind.hpp> 

using namespace boost; 
using namespace std; 

string fmt_str(const string& s, int w, int p) 
{ 
    return (format("%s") % io::group(setw(w), setprecision(p), s)).str(); 
} 

int main() 
{ 
    function<string (int, string)> f = bind(fmt_str, _2, _1, _1); 
    string s = f(15, "Hello"); 
    return 0; 
} 
1

당신은 다시 Boost.Lambda의 문서를 확인하고이 가능하고 무엇을하지 무엇을 볼 수 있습니다. 예를 들어 도트 연산자는 오버로드 할 수 없으므로 이와 같은 람다 식에서 str()과 같은 멤버 함수를 호출 할 수 없습니다.

bind(&format::str, …) 

이 실제로 지금까지 내가 말할 수있는 통화 이외의 모든 연산자 기능 확장 : 당신은 이것에 대한 bind를 사용해야합니다. 포맷 객체를 생성에 관해서는이 같은 것을 통해 그것의 작성을 지연해야합니다

constructor<boost::format>(constant("%s")) // untested 

당신은 모든 여분의 소음 (바인드, 생성자, 상수) 당신은 다소 복잡하고 긴 얻을 것을 볼 람다 표현을 해독하기 어렵다. 가장 좋은 방법은 아마도 그것을 피하고 단순한 함수 객체를 사용하는 것일 것입니다.

struct myfunctor { 
    string operator()(int a, string b) const { 
     return … 
    } 
}; 
… 
void foo() { 
    … 
    boost::function<string(int, string)> f = myfunctor(); 
    … 
}