そのとおりです。残念ながら、UnaryFunction
概念としては次のように書かれています。
BOOST_concept(UnaryFunction,(Func)(Return)(Arg))
{
BOOST_CONCEPT_USAGE(UnaryFunction) { test(is_void<Return>()); }
private:
void test(boost::mpl::false_)
{
f(arg); // "priming the pump" this way keeps msvc6 happy (ICE)
Return r = f(arg);
ignore_unused_variable_warning(r);
}
void test(boost::mpl::true_)
{
f(arg); // <== would have to have std::move(arg)
// here to work, or at least some kind of
// check against copy-constructibility, etc.
}
#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \
&& BOOST_WORKAROUND(__GNUC__, > 3)))
// Declare a dummy construktor to make gcc happy.
// It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type.
// (warning: non-static reference "const double& boost::UnaryFunction<YourClassHere>::arg"
// in class without a constructor [-Wuninitialized])
UnaryFunction();
#endif
Func f;
Arg arg;
};
は左辺値で渡されるためarg
、Boost.Concepts で動作させる方法はありません。直接。ただし、ハックを書くことはできます。有効なチェックを呼び出しているだけなので、 に変換可能f(arg)
な のローカル型を構築できます。あれは:arg
unique_ptr<Bar>
template <typename Function>
void foo(Function f)
{
struct Foo {
operator std::unique_ptr<int>();
};
BOOST_CONCEPT_ASSERT((
boost::UnaryFunction<Function, void, Foo>));
f(std::make_unique<int>(42));
}
またはより一般的に:
template <typename T>
struct AsRvalue {
operator T(); // no definition necessary
};
template <typename Function>
void foo(Function f)
{
BOOST_CONCEPT_ASSERT((
boost::UnaryFunction<Function, void, AsRvalue<std::unique_ptr<int>>>));
f(std::make_unique<int>(42));
}
それはgccとclangでコンパイルされます(ただし、未使用のtypedefについてclangで警告が表示されます)。ただし、その時点で、独自のコンセプトを書き出すだけで機能させる方が明確な場合があります。Piotr のようなものが最も簡単でしょう。