gcc4.7およびboost1.49を使用すると、次の式を使用してis_assignable
戻り値が返されます。true
typedef boost::function<void()> F;
std::is_assignable<F, std::nullptr_t>::value
ただし、このコードはコンパイルに失敗します。
boost::function<void()> f;
f = nullptr;
これらのエラーメッセージを生成します。
In file included from c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function/detail/maybe_include.hpp:13:0,
from c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function/detail/function_iterate.hpp:14,
from c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/preprocessor/iteration/detail/iter/forward1.hpp:47,
from c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function.hpp:64,
from ..\main.cpp:8:
c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function/function_template.hpp: In instantiation of 'static void boost::detail::function::void_function_obj_invoker0<FunctionObj, R>::invoke(boost::detail::function::function_buffer&) [with FunctionObj = std::nullptr_t; R = void]':
c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function/function_template.hpp:907:60: required from 'void boost::function0<R>::assign_to(Functor) [with Functor = std::nullptr_t; R = void]'
c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function/function_template.hpp:722:7: required from 'boost::function0<R>::function0(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = std::nullptr_t; R = void; typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type = int]'
c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function/function_template.hpp:1042:16: required from 'boost::function<R()>::function(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = std::nullptr_t; R = void; typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type = int]'
c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function/function_template.hpp:1083:5: required from 'typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, boost::function<R()>&>::type boost::function<R()>::operator=(Functor) [with Functor = std::nullptr_t; R = void; typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, boost::function<R()>&>::type = boost::function<void()>&]'
..\main.cpp:172:6: required from here
c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function/function_template.hpp:153:11: error: '* f' cannot be used as a function
さらに、この式は次を返しますfalse
。
typedef boost::function<void()> G;
std::is_assignable<G, decltype(NULL)>::value
しかし、このコードはコンパイルされます:
boost::function<void()> g;
g = NULL;
の結果はis_assignable
、の機能を適切に反映していないようですboost::function
。私はここで何か間違ったことをしていますか?(エラーメッセージを理解するのに問題があります。)
タイプ特性は、テンプレートで使用されるクラスの機能を決定するための信頼できる方法であると思われました。C ++ 11で提供されるタイプ特性は、単にboost :: functionと互換性がありませんか?
これにいくつかのコンテキストを与えるために、私はC++11の新機能をよりよく理解するためにいくつかの個人的なプロジェクトに取り組んできました。この特定のプロジェクトでは、「非アクティブ化」できる呼び出し可能な関数を格納するクラスを作成しようとしています。これは大まかに私がやろうとしていることです:
template <typename F>
class callable_function
{
public:
callable_function(F func) : func_(func)
{
/* func_ is initially active */
}
void call()
{
if (/* func_ is active */) func_();
}
void deactivate()
{
/* set func_ to deactive */
}
private:
F func_;
};
/* func_ is active */
およびブロックについては/* set func_ to deactive */
、のプロパティに応じてコンパイル時に選択される2つの異なる実装を提供したいと思いますF
。nullptr
ブールコンテキストに割り当てることができ、ブールコンテキストfunc_
で使用できる場合func_
は、次のものを使用します(これは、組み込み関数ポインター用に選択されるものですstd::function
)。
template <typename F>
class callable_function
{
public:
callable_function(F func) : func_(func) {}
void call()
{
if (func_) func_();
}
void deactivate()
{
func_ = nullptr;
}
private:
F func_;
};
nullptr
に割り当てることができない場合はfunc_
、「アクティブ」ステータスを格納するクラス内に追加のブール値を格納します。この実装は、ファンクターとラムダ関数用に選択されています。
template <typename F>
class callable_function
{
public:
callable_function(F func) : func_(func), active_(true) {}
void call()
{
if (active_) func_();
}
void deactivate()
{
active_ = false;
}
private:
F func_;
bool active_;
};
nullptr
現在はに割り当てることができないため、boost::function
2番目の実装が選択されることを期待します。ただし、はとis_assignable
を返すtrue
ためboost::function
、nullptr
代わりに最初の実装が選択され、関数でコンパイルエラーが発生しdeactivate
ます。