5

boost::formatどういうわけか、で使用できませんboost::lambda。これが私のコードの(うまくいけば)コンパイル可能な簡略化です:

#include <algorithm>
#include <iomanip>
#include <iostream>

#include <boost/assign/list_of.hpp>
#include <boost/format.hpp>
#include <boost/lambda/lambda.hpp>

namespace bl = boost::lambda;

int main()
{
    const std::vector<int> v = boost::assign::list_of(1)(2)(3);
    std::for_each(v.begin(), v.end(), bl::var(std::cout) << std::setw(10) << bl::_1);
    std::for_each(v.begin(), v.end(), bl::var(std::cout) << boost::format("%10d") % bl::_1);
}
  • 最初std::for_eachは期待される出力を生成します
  • 2つ目std::for_eachは、数字のない空白のみを出力します

何故ですか ?私は本当によく知らないboost::lambdaので、ここで明らかなことを見逃しているかもしれません。

ベースの答えを提案しないでくださいstd::copy:私の実際のコードは機能しませんstd::vectorが、機能しますboost::fusion::vectorstd::for_each実際にはboost::fusion::for_each)。

4

2 に答える 2

4

何らかの理由で、コードboost::format("%10d") % bl::_1はラムダの呼び出しごとではなく、すぐに評価されます。

これを防ぐには、と同じように、boost::format("%10d")への呼び出しをラップする必要があります。bl::varstd::cout

残念ながら、これを行うには、Boost.Lambdaがへの呼び出しのリターンタイプを推測する必要がありますがoperator%、これは実行できません。したがって、リターンタイプは、を使用して明示的に指定する必要がありますbl::retstd::cout返されたオブジェクトのコピーではなく直接アクセスするには、この戻りタイプが参照である必要があることに注意してください。

したがって、次のコードが得られ、期待される出力が生成されます。

std::for_each(v.begin(), v.end(), bl::var(std::cout) <<
    bl::ret<const boost::format &>(bl::var(boost::format("%10d")) % bl::_1));
于 2010-12-07T23:44:25.610 に答える
2

私の賭けは、使用されているフォーマットがもはや使用できないという事実に遭遇していることです。

boost::format f("...");

std::string s = f % ... ;
std::string s2 = f % other options...; // FAIL!  f has been changed by the above use!

つまり、フォーマットで % を使用すると、実際には文字列データが % したものに置き換えられます。よりクールなことは、上記の 2 番目の使用がサイレントに失敗することです。

直感に反することは知っていますが、それはそれです。

于 2010-12-07T22:04:10.843 に答える