Boost.Phoenix の Scope-let

Boost.Phoenix では、let を使用して、ローカル変数のような構文を書くことが出来ます。

[ソース]

#include <boost/phoenix/scope.hpp>
#include <boost/phoenix/core.hpp>
#include <boost/phoenix/operator.hpp>
#include <boost/phoenix/statement.hpp>
#include <iostream>

int
main(){
    namespace phx = boost::phoenix;
    using phx::arg_names::arg1;
    using phx::local_names::_a;
    using phx::local_names::_b;
    using phx::local_names::_c;
    using phx::local_names::_i;
    
    int n = let(_a = 123, _b = 456)[
        _a + _b                    // 123 + 456 を返す
    ]();
    std::cout << n << std::endl;
    
    // arg1 を参照で受け取る
    let(_a = arg1, _b = 456)[
        _a = _b                    // arg1 に対して代入
    ](n);
    std::cout << n << std::endl;
    
    // arg1 を値で受け取る
    let(_a = phx::val(arg1), _b = 123)[
        _a = _b                    // arg1 は影響されない
    ](n);
    std::cout << n << std::endl;
    
    // 複数行の場合は、最後の結果を貸す
    n = phx::let(_a = 100, _b = arg1)[
        _a + _b,
        _a * _b,
        _a / _b            // これが返される
    ](20);
    std::cout << n << std::endl;
    
    // ネストして記述
    phx::let(_a = 1, _b = phx::val(", world"))[
        phx::let(_a = phx::val("hello"), _b = _b)[
            std::cout << _a << _b << std::endl
        ]
    ]();
    /* 1.47.0 だとネストしている let で _b = _b をしないとコンパイルエラーになる
    phx::let(_a = 1, _b = phx::val(", world"))[
        phx::let(_a = phx::val("hello"))[
            std::cout << _a << _b << std::endl
        ]
    ]();
    */
    // 他の statement の結果を返すことも
    int sum = phx::let(_i = 0, _a = 0)[
        phx::for_(phx::nothing, _i < arg1, ++_i)[
            _a += _i
        ],
        _a
    ](10);
    
    return 0;

[出力]

579
456
456
5
hello, world
45

ネストして、let を記述する場合は、再度 _b = _b の様に定義し直さないとダメみたいです…。

[boost]

  • ver 1.47.0