以下のコードがVisual C++ 12.0でコンパイルエラーになります。Boostのバージョンは1.55です。
#include <boost/iterator/iterator_concepts.hpp> int main() { }
出力 http://melpon.org/wandbox/permlink/oJdAALJZbyRJgIiG
iterator_concepts.hpp(43): error C2448: 'BOOST_concept' : 関数の定義が間違っています。
この辺りを見た感じ、BOOST_concept
マクロ展開が怪しそうなので、/EP
コンパイラプションをつけてマクロを展開したソースコードをチェックしてみました。
マクロ展開したソースコードの一部抜粋
namespace boost_concepts { BOOST_concept(ReadableIterator,(Iterator)) : boost::Assignable<Iterator> , boost::CopyConstructible<Iterator> { typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type; typedef typename boost::detail::iterator_traits<Iterator>::reference reference; enum { boost_concept_check50 = sizeof(::boost::concepts::require_((void(*)(boost::concepts::usage_requirements<ReadableIterator>))0)) }; ~ReadableIterator() { value_type v = *i; boost::ignore_unused_variable_warning(v); } private: Iterator i; };
BOOST_conceptが展開されていませんでした。定義されてから使用されるまでの間にundef
されてしまっているようです。しかし、ソースコードを見ても
<boost/iterator/iterator_concepts.hpp> ↓ <boost/concept_check.hpp> BOOST_concept defineされる ↓ BOOST_concept undefされる <boost/concept_check.hpp>おわり ↓ BOOST_concept defineされる ↓ BOOST_concept使用 ↓ BOOST_concept undefされる ↓ <boost/iterator/iterator_concepts.hpp>おわり
と、undefされているように見えないんですよね…
もしかして一度undefしてしまうと、再度defineしてもundefされたままと見なして展開してくれない、プリプロセッサの不具合ではないかと思ったのですが、
#define A typename T #undef A #define A typename T template < A > struct hoge {}; #undef A int main() { hoge<int> h; }
が普通に動いたのでそれはなさそうです。 Visual C++では<boost/concept/detail/concept_undef.hpp>の、
# undef BOOST_concept_typename # undef BOOST_concept
をコメントアウトするか、もしくは<boost/concept_check.hpp>の一番最後から3行目、1082行目の
# include <boost/concept/detail/concept_undef.hpp>
をコメントアウトすることで、最初のソースコードのコンパイルが通ります。
本当の原因は結局わかりませんでした。