Template Deduction Problem when adding equivalence check in std::enable_if - c++

I am trying to benchmark different ways to sum. I'd like using an interface as follows
avx2_sum<sum_algorithm::normal>(container.begin(), container.end());
However, my attempt
enum class sum_algorithm: char{
normal,
kahan,
twofold_fast //https://arxiv.org/pdf/1401.0248.pdf
};
template<sum_algorithm algorithm_t, typename iterator_t, typename sum_t = typename std::iterator_traits<iterator_t>::value_type,
std::enable_if_t<std::is_same<sum_t, double>::value && (algorithm_t == sum_algorithm::normal)> = true>
sum_t avx2_sum(const iterator_t begin, const iterator_t end) noexcept {
// SIMD-parallel summation stage
auto running_sums = _mm256_set1_pd(0);
auto iterator_skip = 256/sizeof(sum_t);
for (iterator_t it = begin; it + iterator_skip < end; it += iterator_skip){
//TODO: flip to double load reduction
running_sums = _mm256_add_pd(_mm256_load_pd(it), running_sums);
}
// Serial summation
running_sums = _mm256_hadd_pd(running_sums, running_sums);
running_sums = _mm256_hadd_pd(running_sums, running_sums);
return _mm256_cvtsd_f64(running_sums);
}
produces the following:
error: no matching function for call to 'avx2_sum'
std::cout << "avx2<float, normal>: " << accumulators::avx2_sum<algo::normal>(float_arr.begin(), float_arr.end()) <<"\n";
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/rlfactory/dev/thommmj1/cppbenchmarks/cpp_utils/algorithms/cpu_accumulators.hpp:55:11: note: candidate template ignored: requirement 'std::is_same<float, double>::value' was not satisfied [with algorithm_t = accumulators::sum_algorithm::normal, iterator_t = __gnu_cxx::__normal_iterator<float *, std::vector<float, std::allocator<float> > >, sum_t = float]
sum_t avx2_sum(const iterator_t begin, const iterator_t end) noexcept {
^
/home/rlfactory/dev/thommmj1/cppbenchmarks/cpp_utils/algorithms/cpu_accumulators.hpp:71:11: note: candidate template ignored: substitution failure [with algorithm_t = accumulators::sum_algorithm::normal, iterator_t = __gnu_cxx::__normal_iterator<float *, std::vector<float, std::allocator<float> > >, sum_t = float]: a non-type template parameter cannot have type 'std::enable_if_t<std::is_same<float, float>::value && ((sum_algorithm)'\x00' == sum_algorithm::normal)>' (aka 'void')
sum_t avx2_sum(const iterator_t begin, const iterator_t end) noexcept {
^
/home/rlfactory/dev/thommmj1/cppbenchmarks/cpp_utils/algorithms/cpu_accumulators.hpp:87:11: note: candidate template ignored: requirement 'std::is_same<float, double>::value' was not satisfied [with algorithm_t = accumulators::sum_algorithm::normal, iterator_t = __gnu_cxx::__normal_iterator<float *, std::vector<float, std::allocator<float> > >, sum_t = float]
sum_t avx2_sum(const iterator_t begin, const iterator_t end) noexcept {
^
/home/rlfactory/dev/thommmj1/cppbenchmarks/cpp_utils/algorithms/cpu_accumulators.hpp:109:11: note: candidate template ignored: requirement 'std::is_same<float, float>::value && ((accumulators::sum_algorithm)'\x00' == sum_algorithm::kahan)' was not satisfied [with algorithm_t = accumulators::sum_algorithm::normal, iterator_t = __gnu_cxx::__normal_iterator<float *, std::vector<float, std::allocator<float> > >, sum_t = float]
sum_t avx2_sum(const iterator_t begin, const iterator_t end) noexcept {
I don't understand how deduction doesn't work here. Without the algorithm_t template portion and check, it works just fine. Perhaps it's due to my using statement? using algo = accumulators::sum_algorithm;

Related

How to make user-defined types work on ranges algorithms with operator overloading in c++20? [duplicate]

In MyRect.h:
struct MyRect
{
MyRect(std::initializer_list<int> i);
MyRect();
int16_t m_left=0, m_right=0, m_top=0, m_bottom=0 ;
int16_t no_sequence=0 ;
int16_t i=-1 ;
bool selected=false ;
} ;
bool operator==(const MyRect& r1, const MyRect& r2) ;
bool operator<(const MyRect& r1, const MyRect& r2);
In MyRect.cpp:
bool operator==(const MyRect& r1, const MyRect& r2)
{
return r1.m_left==r2.m_left &&
r1.m_right==r2.m_right &&
r1.m_top==r2.m_top &&
r1.m_bottom==r2.m_bottom ;
}
bool operator<(const MyRect& r1, const MyRect& r2)
{
if (r1.m_left != r2.m_left)
return r1.m_left < r2.m_left;
if (r1.m_right != r2.m_right)
return r1.m_right < r2.m_right;
if (r1.m_top != r2.m_top)
return r1.m_top < r2.m_top;
if (r1.m_bottom != r2.m_bottom)
return r1.m_bottom < r2.m_bottom;
//if we got here, r1==r2
return false;
}
In binpack.cpp:
#include "MyRect.h"
...
vector<MyRect> selected_neighboors ;
std::sort(selected_neighboors.begin(), selected_neighboors.end()) ;
Using g++10 (C++20) binpack.cpp compiles. No issues.
If I change to:
ranges::sort(selected_neighboors);
It does not compile any more.
/home/edouda/linkedboxdraw/binpack.cpp: In function ‘void collapse(std::vector<MyRect>&)’:
/home/edouda/linkedboxdraw/binpack.cpp:617:36: error: no match for call to ‘(const std::ranges::__sort_fn) (std::vector<MyRect>&)’
617 | ranges::sort(selected_neighboors) ;
| ^
In file included from /usr/include/c++/10/algorithm:64,
from /home/edouda/linkedboxdraw/MyRect.h:14,
from /home/edouda/linkedboxdraw/binpack.h:12,
from /home/edouda/linkedboxdraw/binpack.cpp:8:
/usr/include/c++/10/bits/ranges_algo.h:2019:7: note: candidate: ‘template<class _Iter, class _Sent, class _Comp, class _Proj> requires (random_access_iterator<_Iter>) && (sentinel_for<_Sent, _Iter>) && (sortable<_Iter, _Comp, _Proj>) constexpr _Iter std::ranges::__sort_fn::operator()(_Iter, _Sent, _Comp, _Proj) const’
2019 | operator()(_Iter __first, _Sent __last,
| ^~~~~~~~
/usr/include/c++/10/bits/ranges_algo.h:2019:7: note: template argument deduction/substitution failed:
/home/edouda/linkedboxdraw/binpack.cpp:617:36: note: candidate expects 4 arguments, 1 provided
617 | ranges::sort(selected_neighboors) ;
| ^
In file included from /usr/include/c++/10/algorithm:64,
from /home/edouda/linkedboxdraw/MyRect.h:14,
from /home/edouda/linkedboxdraw/binpack.h:12,
from /home/edouda/linkedboxdraw/binpack.cpp:8:
/usr/include/c++/10/bits/ranges_algo.h:2032:7: note: candidate: ‘constexpr std::ranges::borrowed_iterator_t<_Range> std::ranges::__sort_fn::operator()(_Range&&, _Comp, _Proj) const [with _Range = std::vector<MyRect>&; _Comp = std::ranges::less; _Proj = std::identity; std::ranges::borrowed_iterator_t<_Range> = std::conditional<true, __gnu_cxx::__normal_iterator<MyRect*, std::vector<MyRect> >, std::ranges::dangling>::type]’
2032 | operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
| ^~~~~~~~
/usr/include/c++/10/bits/ranges_algo.h:2032:7: note: constraints not satisfied
In file included from /usr/include/c++/10/compare:39,
from /usr/include/c++/10/bits/stl_pair.h:65,
from /usr/include/c++/10/bits/stl_algobase.h:64,
from /usr/include/c++/10/vector:60,
from /home/edouda/linkedboxdraw/MyRect.h:12,
from /home/edouda/linkedboxdraw/binpack.h:12,
from /home/edouda/linkedboxdraw/binpack.cpp:8:
/usr/include/c++/10/concepts: In instantiation of ‘constexpr std::ranges::borrowed_iterator_t<_Range> std::ranges::__sort_fn::operator()(_Range&&, _Comp, _Proj) const [with _Range = std::vector<MyRect>&; _Comp = std::ranges::less; _Proj = std::identity; std::ranges::borrowed_iterator_t<_Range> = std::conditional<true, __gnu_cxx::__normal_iterator<MyRect*, std::vector<MyRect> >, std::ranges::dangling>::type]’:
/home/edouda/linkedboxdraw/binpack.cpp:617:36: required from here
/usr/include/c++/10/concepts:338:13: required for the satisfaction of ‘invocable<_Fn, _Args ...>’ [with _Fn = std::ranges::less&; _Args = {value_type<MyRect>&, value_type<MyRect>&}]
/usr/include/c++/10/concepts:342:13: required for the satisfaction of ‘regular_invocable<_Fn, _Args ...>’ [with _Fn = std::ranges::less&; _Args = {value_type<MyRect>&, value_type<MyRect>&}]
/usr/include/c++/10/concepts:346:13: required for the satisfaction of ‘predicate<_Rel, _Tp, _Tp>’ [with _Rel = std::ranges::less&; _Tp = MyRect&]
/usr/include/c++/10/concepts:351:13: required for the satisfaction of ‘relation<_Rel, _Tp, _Up>’ [with _Rel = std::ranges::less&; _Tp = MyRect&; _Up = MyRect&]
/usr/include/c++/10/concepts:361:13: required for the satisfaction of ‘strict_weak_order<_Fn&, typename std::__detail::__iter_traits_impl<typename std::remove_cv<typename std::remove_reference<_Arg>::type>::type, std::indirectly_readable_traits<typename std::remove_cv<typename std::remove_reference<_Arg>::type>::type> >::type::value_type&, typename std::__detail::__iter_traits_impl<typename std::remove_cv<typename std::remove_reference<_Arg>::type>::type, std::indirectly_readable_traits<typename std::remove_cv<typename std::remove_reference<_Arg>::type>::type> >::type::value_type&>’ [with _Fn = std::ranges::less; _Arg = std::projected<__gnu_cxx::__normal_iterator<MyRect*, std::vector<MyRect, std::allocator<MyRect> > >, std::identity>; _Arg = std::projected<__gnu_cxx::__normal_iterator<MyRect*, std::vector<MyRect, std::allocator<MyRect> > >, std::identity>]
/usr/include/c++/10/bits/iterator_concepts.h:690:13: required for the satisfaction of ‘indirect_strict_weak_order<_Rel, std::projected<_Iter, _Proj>, std::projected<_Iter, _Proj> >’ [with _Rel = std::ranges::less; _Iter = __gnu_cxx::__normal_iterator<MyRect*, std::vector<MyRect, std::allocator<MyRect> > >; _Proj = std::identity]
/usr/include/c++/10/bits/iterator_concepts.h:865:13: required for the satisfaction of ‘sortable<decltype (std::__detail::__ranges_begin(declval<_Container&>())), _Comp, _Proj>’ [with _Container = std::vector<MyRect, std::allocator<MyRect> >&; _Comp = std::ranges::less; _Proj = std::identity]
/usr/include/c++/10/concepts:338:25: note: the expression ‘is_invocable_v<_Fn, _Args ...> [with _Fn = std::ranges::less&; _Args = {value_type<MyRect>&, value_type<MyRect>&}]’ evaluated to ‘false’
338 | concept invocable = is_invocable_v<_Fn, _Args...>;
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
make[2]: *** [CMakeFiles/latuile.dir/build.make:76: CMakeFiles/latuile.dir/binpack.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:78: CMakeFiles/latuile.dir/all] Error 2
make: *** [Makefile:95: all] Error 2
ranges::sort uses ranges::less to compare MyRect by default, which is defined in [range.cmp]:
struct ranges::less {
template<class T, class U>
constexpr bool operator()(T&& t, U&& u) const;
using is_transparent = unspecified;
};
template<class T, class U>
constexpr bool operator()(T&& t, U&& u) const;
Constraints: T and U satisfy totally_­ordered_­with.
Its operator() requires that T and U must satisfy total_ordered_with:
template<class T, class U>
concept totally_­ordered_­with =
totally_­ordered<T> && totally_­ordered<U> && ...
which requires that T must satisfy totally_ordered:
template<class T>
concept totally_­ordered =
equality_­comparable<T> && partially-ordered-with<T, T>;
which requires that T must satisfy partially-ordered-with:
template<class T, class U>
concept partially-ordered-with = // exposition only
requires(const remove_reference_t<T>& t, const remove_reference_t<U>& u) {
{ t < u } -> boolean-testable;
{ t > u } -> boolean-testable;
{ t <= u } -> boolean-testable;
{ t >= u } -> boolean-testable;
{ u < t } -> boolean-testable;
{ u > t } -> boolean-testable;
{ u <= t } -> boolean-testable;
{ u >= t } -> boolean-testable;
};
which requires that the full set of the relational operators must be well-formed.
Since you did not define a suitable operator>, operator<= and other relational operators for MyRect, the constraints are not satisfied.
You can add operator<=> to MyRect to make it totally_ordered, or use unconstrained std::less for comparison:
std::vector<MyRect> selected_neighboors;
ranges::sort(selected_neighboors, std::less{});

Boost::Variant "Error: no match for call to [...]" on visitor operator overload

I'm trying to implement a function to pass from an AST from an expression grammar to a string, and then test if it's correct comparing it with the correct string. To do that I implemented a visitor to visit a Boost::Variant variable and overloaded a function named "getString".
I'm getting a lot of errors about wrong definitions, and I've been looking through StackOverflow for similar problems but anything worked.
Errors (repeated for each of the overloaded operators on visitor):
In file included from /usr/include/boost/spirit/home/support/info.hpp:14,
from /usr/include/boost/spirit/home/qi/domain.hpp:16,
from /usr/include/boost/spirit/home/qi/meta_compiler.hpp:15,
from /usr/include/boost/spirit/home/qi/action/action.hpp:14,
from /usr/include/boost/spirit/home/qi/action.hpp:14,
from /usr/include/boost/spirit/home/qi.hpp:14,
from /usr/include/boost/spirit/include/qi.hpp:16,
from src/./Expression.cpp:2,
from src/main.cpp:1:
/usr/include/boost/variant/variant.hpp: In instantiation of 'boost::detail::variant::invoke_visitor<Visitor>::result_type boost::detail::variant::invoke_visitor<Visitor>::internal_visit(T&, int) [with T = std::basic_string<char>; Visitor = const testing::visitor; boost::detail::variant::invoke_visitor<Visitor>::result_type = std::basic_string<char>]':
/usr/include/boost/variant/detail/visitation_impl.hpp:114:9: required from 'typename Visitor::result_type boost::detail::variant::visitation_impl_invoke_impl(int, Visitor&, VoidPtrCV, T*, mpl_::true_) [with Visitor = boost::detail::variant::invoke_visitor<const testing::visitor>; VoidPtrCV = void*; T = std::basic_string<char>; typename Visitor::result_type = std::basic_string<char>; mpl_::true_ = mpl_::bool_<true>]'
/usr/include/boost/variant/detail/visitation_impl.hpp:154:41: required from 'typename Visitor::result_type boost::detail::variant::visitation_impl_invoke(int, Visitor&, VoidPtrCV, T*, NoBackupFlag, int) [with Visitor = boost::detail::variant::invoke_visitor<const testing::visitor>; VoidPtrCV = void*; T = std::basic_string<char>; NoBackupFlag = boost::variant<std::basic_string<char>, double, bool, boost::recursive_wrapper<ast::unary>, boost::recursive_wrapper<ast::expression> >::has_fallback_type_; typename Visitor::result_type = std::basic_string<char>]'
/usr/include/boost/variant/detail/visitation_impl.hpp:238:5: required from 'typename Visitor::result_type boost::detail::variant::visitation_impl(int, int, Visitor&, VoidPtrCV, mpl_::false_, NoBackupFlag, Which*, step0*) [with Which = mpl_::int_<0>; step0 = boost::detail::variant::visitation_impl_step<boost::mpl::l_iter<boost::mpl::l_item<mpl_::long_<5>, std::basic_string<char>, boost::mpl::l_item<mpl_::long_<4>, double, boost::mpl::l_item<mpl_::long_<3>, bool, boost::mpl::l_item<mpl_::long_<2>, boost::recursive_wrapper<ast::unary>, boost::mpl::l_item<mpl_::long_<1>, boost::recursive_wrapper<ast::expression>, boost::mpl::l_end> > > > > >, boost::mpl::l_iter<boost::mpl::l_end> >; Visitor = boost::detail::variant::invoke_visitor<const testing::visitor>; VoidPtrCV = void*; NoBackupFlag = boost::variant<std::basic_string<char>, double, bool, boost::recursive_wrapper<ast::unary>, boost::recursive_wrapper<ast::expression> >::has_fallback_type_; typename Visitor::result_type = std::basic_string<char>; mpl_::false_ = mpl_::bool_<false>]'
/usr/include/boost/variant/variant.hpp:2384:48: required from 'static typename Visitor::result_type boost::variant<T0, TN>::internal_apply_visitor_impl(int, int, Visitor&, VoidPtrCV) [with Visitor = boost::detail::variant::invoke_visitor<const testing::visitor>; VoidPtrCV = void*; T0_ = std::basic_string<char>; TN = {double, bool, boost::recursive_wrapper<ast::unary>, boost::recursive_wrapper<ast::expression>}; typename Visitor::result_type = std::basic_string<char>]'
/usr/include/boost/variant/variant.hpp:2398:43: required from 'typename Visitor::result_type boost::variant<T0, TN>::internal_apply_visitor(Visitor&) [with Visitor = boost::detail::variant::invoke_visitor<const testing::visitor>; T0_ = std::basic_string<char>; TN = {double, bool, boost::recursive_wrapper<ast::unary>, boost::recursive_wrapper<ast::expression>}; typename Visitor::result_type = std::basic_string<char>]'
/usr/include/boost/variant/variant.hpp:2423:52: required from 'typename Visitor::result_type boost::variant<T0, TN>::apply_visitor(Visitor&) [with Visitor = const testing::visitor; T0_ = std::basic_string<char>; TN = {double, bool, boost::recursive_wrapper<ast::unary>, boost::recursive_wrapper<ast::expression>}; typename Visitor::result_type = std::basic_string<char>]'
/usr/include/boost/variant/detail/apply_visitor_unary.hpp:84:43: required from 'typename Visitor::result_type boost::apply_visitor(const Visitor&, Visitable&) [with Visitor = testing::visitor; Visitable = boost::variant<std::basic_string<char>, double, bool, boost::recursive_wrapper<ast::unary>, boost::recursive_wrapper<ast::expression> >; typename Visitor::result_type = std::basic_string<char>]'
src/./Printer.cpp:29:64: required from here
/usr/include/boost/variant/variant.hpp:1046:24: error: no match for call to '(const testing::visitor) (std::basic_string<char>&)'
return visitor_(operand);
~~~~~~~~^~~~~~~~~
In file included from src/main.cpp:2:
src/./Printer.cpp:20:21: note: candidate: 'std::string testing::visitor::operator()(std::string&)' <near match>
std::string operator()(std::string& v) { return v; }
^~~~~~~~
src/./Printer.cpp:20:21: note: passing 'const testing::visitor*' as 'this' argument discards qualifiers
src/./Printer.cpp:21:21: note: candidate: 'std::string testing::visitor::operator()(double&)'
std::string operator()(double& v) { return boost::lexical_cast<std::string>(v); }
^~~~~~~~
src/./Printer.cpp:21:21: note: no known conversion for argument 1 from 'std::basic_string<char>' to 'double&'
src/./Printer.cpp:22:21: note: candidate: 'std::string testing::visitor::operator()(bool&)'
std::string operator()(bool& b) { return b ? "True" : "False"; }
^~~~~~~~
src/./Printer.cpp:22:21: note: no known conversion for argument 1 from 'std::basic_string<char>' to 'bool&'
src/./Printer.cpp:24:21: note: candidate: 'std::string testing::visitor::operator()(ast::expression&)'
std::string operator()(ast::expression& e) { return getString(e); }
^~~~~~~~
src/./Printer.cpp:24:21: note: no known conversion for argument 1 from 'std::basic_string<char>' to 'ast::expression&'
src/./Printer.cpp:25:21: note: candidate: 'std::string testing::visitor::operator()(ast::unary&)'
std::string operator()(ast::unary& e) { return getString(e); }
^~~~~~~~
src/./Printer.cpp:25:21: note: no known conversion for argument 1 from 'std::basic_string<char>' to 'ast::unary&'
Printer.cpp:
#include <boost/lexical_cast.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/variant/recursive_wrapper.hpp>
#include <string>
#include "AST.hpp"
namespace testing {
std::string getString(ast::expression& e);
std::string getString(ast::operation& op);
std::string getString(ast::unary& op);
std::string getString(ast::optoken& opt);
struct visitor : boost::static_visitor<std::string>
{
std::string operator()(std::string& v) { return v; }
std::string operator()(double& v) { return boost::lexical_cast<std::string>(v); }
std::string operator()(bool& b) { return b ? "True" : "False"; }
std::string operator()(ast::expression& e) { return getString(e); }
std::string operator()(ast::unary& e) { return getString(e); }
};
std::string getString(ast::expression& e) {
std::string s = boost::apply_visitor(visitor(), e.first);
std::string result = "( " + s;
for (auto it = e.rest.begin(); it != e.rest.end(); ++it) {
result += getString(*it);
}
result += " )";
return result;
}
std::string getString(ast::unary& op) {
std::string s = boost::apply_visitor(visitor(), op.operand_);
return " " + getString(op.operator_) + " " + s;
}
std::string getString(ast::operation& op) {
std::string s = boost::apply_visitor(visitor(), op.operand_);
return " " + getString(op.operator_) + " " + s;
}
std::string getString(ast::optoken& opt) {
switch(opt) {
case ast::op_plus: return "+";
case ast::op_minus: return "-";
case ast::op_times: return "*";
case ast::op_divide: return "/";
case ast::op_not: return "!";
case ast::op_equal: return "==";
case ast::op_not_equal: return "!=";
case ast::op_less: return "<";
case ast::op_less_equal: return "<=";
case ast::op_greater: return ">";
case ast::op_greater_equal: return ">=";
case ast::op_and: return "&&";
case ast::op_or: return "||";
}
return "undf";
}
}
AST.hpp
namespace ast
{
struct unary;
struct expression;
typedef boost::variant<
std::string,
double,
bool,
boost::recursive_wrapper<unary>,
boost::recursive_wrapper<expression>
> operand;
enum optoken
{
op_plus,
op_minus,
op_times,
op_divide,
op_positive,
op_negative,
op_not,
op_equal,
op_not_equal,
op_less,
op_less_equal,
op_greater,
op_greater_equal,
op_and,
op_or
};
struct operation {
optoken operator_;
operand operand_;
};
struct unary {
optoken operator_;
operand operand_;
};
struct expression
{
operand first;
std::list<operation> rest;
};
}
Your visitor methods should be const:
std::string operator()(std::string& v) const { return v; }
std::string operator()(double& v) const { return boost::lexical_cast<std::string>(v); }
std::string operator()(bool& b) const { return b ? "True" : "False"; }
std::string operator()(ast::expression& e) const { return getString(e); }
std::string operator()(ast::unary& e) const { return getString(e); }

C++ templates, default argument as a method

For this implementation of selection sort:
template <typename Iterator, typename Compare>
void sort(Iterator begin, Iterator end, Compare comp) {
for (auto i = begin; i != end; ++i) {
auto min = i;
for (auto j = i + 1; j != end; ++j) {
if (comp(*j, *min)) {
min = j;
}
}
std::swap(*min, *i);
}
}
How should I modify it so that Compare comp should be std::less method if last parameter is skipped for sort method?
I tried function overloading by introducing another method:
template <typename Iterator>
void sort(Iterator begin, Iterator end) {
sort(begin, end, std::less<std::iterator_traits<Iterator>::value_type>());
}
But it gave errors like:
In file included from ../src/selection_sort_demo.cpp:1:
../include/selection_sort.hpp:24:29: error: template argument for template type parameter must be a type; did you forget 'typename'?
sort(begin, end, std::less<std::iterator_traits<Iterator>::value_type>());
^
typename
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../../../include/c++/6.3.1/bits/stl_function.h:380:21: note: template parameter is declared here
template<typename _Tp>
^
In file included from ../src/selection_sort_demo.cpp:1:
../include/selection_sort.hpp:24:2: error: call to 'sort' is ambiguous
sort(begin, end, std::less<std::iterator_traits<Iterator>::value_type>());
^~~~
../src/selection_sort_demo.cpp:22:13: note: in instantiation of function template specialization 'selection::sort<__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > >' requested here
selection::sort(v.begin(), v.end());
^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../../../include/c++/6.3.1/bits/stl_algo.h:4727:5: note: candidate function [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >, _Compare = std::less<int>]
sort(_RandomAccessIterator __first, _RandomAccessIterator __last,
^
../include/selection_sort.hpp:7:6: note: candidate function [with Iterator = __gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >, Compare = std::less<int>]
void sort(Iterator begin, Iterator end, Compare comp)
^
2 errors generated.
[2/4] Compiling cpp object 'test/testexe#exe/selection_sort_test.cpp.o'
FAILED: test/testexe#exe/selection_sort_test.cpp.o
clang++ '-Itest/testexe#exe' '-Itest' '-I../test' '-I../include' '-Wall' '-Winvalid-pch' '-Wnon-virtual-dtor' '-std=c++14' '-O0' '-g' '-pthread' '-MMD' '-MQ' 'test/testexe#exe/selection_sort_test.cpp.o' '-MF' 'test/testexe#exe/selection_sort_test.cpp.o.d' -o 'test/testexe#exe/selection_sort_test.cpp.o' -c ../test/selection_sort_test.cpp
In file included from ../test/selection_sort_test.cpp:2:
../include/selection_sort.hpp:24:29: error: template argument for template type parameter must be a type; did you forget 'typename'?
sort(begin, end, std::less<std::iterator_traits<Iterator>::value_type>());
^
typename
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../../../include/c++/6.3.1/bits/stl_function.h:380:21: note: template parameter is declared here
template<typename _Tp>
^
In file included from ../test/selection_sort_test.cpp:2:
../include/selection_sort.hpp:24:2: error: call to 'sort' is ambiguous
sort(begin, end, std::less<std::iterator_traits<Iterator>::value_type>());
^~~~
../test/selection_sort_test.cpp:17:13: note: in instantiation of function template specialization 'selection::sort<__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > >' requested here
selection::sort(v1.begin(), v1.end());
^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../../../include/c++/6.3.1/bits/stl_algo.h:4727:5: note: candidate function [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >, _Compare = std::less<int>]
sort(_RandomAccessIterator __first, _RandomAccessIterator __last,
^
../include/selection_sort.hpp:7:6: note: candidate function [with Iterator = __gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >, Compare = std::less<int>]
void sort(Iterator begin, Iterator end, Compare comp)
^
2 errors generated.
Since it's c++14:
template <typename Iterator, typename Compare = std::less<> >
void sort(Iterator begin, Iterator end, Compare comp = Compare())
{
for (auto i = begin; i != end; ++i) {
auto min = i;
for (auto j = i + 1; j != end; ++j) {
if (comp(*j, *min)) {
min = j;
}
}
std::swap(*min, *i);
}
}
c++11:
template <typename Iterator, typename Compare = std::less< typename std::iterator_traits<Iterator>::value_type > >
void sort(Iterator begin, Iterator end, Compare comp = Compare())
{
for (auto i = begin; i != end; ++i) {
auto min = i;
for (auto j = i + 1; j != end; ++j) {
if (comp(*j, *min)) {
min = j;
}
}
std::swap(*min, *i);
}
}
Explanation:
We have to offer the compiler both a default type in the template argument list and a default function argument list.
For explanation of std::less<> since c++14 see:
http://en.cppreference.com/w/cpp/utility/functional/less
You were right, but forgot the typename keyword. Check this:
template <typename Iterator>
void sort(Iterator begin, Iterator end) {
sort(begin, end, std::less<typename std::iterator_traits<Iterator>::value_type>());
}
Probably you wanted default template argument, but this works too.

Making FUSION work to display the contents of a structure

The purpose of the following code is to display the contents of a structure. It is based on this answer.
#include <iostream>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/for_each.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/range_c.hpp>
#include <boost/bind.hpp>
struct Node {
int a = 4;
double b = 2.2;
};
BOOST_FUSION_ADAPT_STRUCT(Node, b)
struct print_visitor {
template <class Index, class C> void operator()(Index, C &c) {
std::cout << boost::fusion::extension::struct_member_name<
C, Index::value>::call() << "="
<< boost::fusion::at<Index>(c) << std::endl;
}
};
template <class C> void print_fields(C &c) {
typedef boost::mpl::range_c<
int, 0, boost::fusion::result_of::size<C>::type::value> range;
boost::mpl::for_each<range>(
boost::bind<void>(print_visitor(), _1, boost::ref(c)));
}
int main() {
Node n;
print_fields(n);
}
The compiler (gcc version 4.8.2) complains:
invalid use of incomplete type ‘struct boost::fusion::result_of::at<Node, mpl_::integral_c<int, 0> >’
typedef typename T::type type;
What is the reason and how can I resolve this?
Here is the complete output of the compiler:
-*- mode: compilation; default-directory: "~/SearchLib/AstarWithPolicies/temp/" -*-
Compilation started at Thu Dec 10 11:54:27
make -k
g++ -Wall -Wextra -Werror -std=c++11 -pedantic -I ~/boost_1_59_0 -I /usr/include/cairomm-1.0/ -I /usr/include/cairo/ -I /usr/include/sigc++-2.0/ -I /usr/lib/x86_64-linux-gnu/sigc++-2.0/include/ -I /usr/include/freetype2/ -g -c temp.cpp
In file included from /home/meir/boost_1_59_0/boost/utility/enable_if.hpp:15:0,
from /home/meir/boost_1_59_0/boost/fusion/support/tag_of.hpp:11,
from /home/meir/boost_1_59_0/boost/fusion/support/category_of.hpp:12,
from /home/meir/boost_1_59_0/boost/fusion/adapted/struct/detail/extension.hpp:14,
from /home/meir/boost_1_59_0/boost/fusion/adapted/struct/adapt_struct.hpp:27,
from temp.cpp:7:
/home/meir/boost_1_59_0/boost/core/enable_if.hpp: In instantiation of ‘struct boost::lazy_disable_if_c<false, boost::fusion::result_of::at<Node, mpl_::integral_c<int, 0> > >’:
/home/meir/boost_1_59_0/boost/core/enable_if.hpp:70:10: required from ‘struct boost::lazy_disable_if<boost::is_const<Node>, boost::fusion::result_of::at<Node, mpl_::integral_c<int, 0> > >’
/home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic_fwd.hpp:102:5: required by substitution of ‘template<class N, class Sequence> constexpr typename boost::lazy_disable_if<boost::is_const<Sequence>, boost::fusion::result_of::at<Sequence, N> >::type boost::fusion::at(Sequence&) [with N = mpl_::integral_c<int, 0>; Sequence = Node]’
temp.cpp:26:48: required from ‘void print_visitor::operator()(Index, C&) [with Index = mpl_::integral_c<int, 0>; C = Node]’
/home/meir/boost_1_59_0/boost/bind/bind.hpp:315:34: required from ‘void boost::_bi::list2<A1, A2>::operator()(boost::_bi::type<void>, F&, A&, int) [with F = print_visitor; A = boost::_bi::list1<mpl_::integral_c<int, 0>&>; A1 = boost::arg<1>; A2 = boost::reference_wrapper<Node>]’
/home/meir/boost_1_59_0/boost/bind/bind.hpp:907:50: required from ‘boost::_bi::bind_t<R, F, L>::result_type boost::_bi::bind_t<R, F, L>::operator()(A1&&) [with A1 = mpl_::integral_c<int, 0>&; R = void; F = print_visitor; L = boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> >; boost::_bi::bind_t<R, F, L>::result_type = void]’
/home/meir/boost_1_59_0/boost/mpl/for_each.hpp:78:25: required from ‘static void boost::mpl::aux::for_each_impl<false>::execute(Iterator*, LastIterator*, TransformFunc*, F) [with Iterator = boost::mpl::r_iter<mpl_::integral_c<int, 0> >; LastIterator = boost::mpl::r_iter<mpl_::integral_c<int, 1> >; TransformFunc = boost::mpl::identity<mpl_::na>; F = boost::_bi::bind_t<void, print_visitor, boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> > >]’
/home/meir/boost_1_59_0/boost/mpl/for_each.hpp:105:97: required from ‘void boost::mpl::for_each(F, Sequence*, TransformOp*) [with Sequence = boost::mpl::range_c<int, 0, 1>; TransformOp = boost::mpl::identity<mpl_::na>; F = boost::_bi::bind_t<void, print_visitor, boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> > >]’
/home/meir/boost_1_59_0/boost/mpl/for_each.hpp:118:48: required from ‘void boost::mpl::for_each(F, Sequence*) [with Sequence = boost::mpl::range_c<int, 0, 1>; F = boost::_bi::bind_t<void, print_visitor, boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> > >]’
temp.cpp:34:62: required from ‘void print_fields(C&) [with C = Node]’
temp.cpp:39:19: required from here
/home/meir/boost_1_59_0/boost/core/enable_if.hpp:63:30: error: invalid use of incomplete type ‘struct boost::fusion::result_of::at<Node, mpl_::integral_c<int, 0> >’
typedef typename T::type type;
^
In file included from /home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic/begin.hpp:14:0,
from /home/meir/boost_1_59_0/boost/fusion/algorithm/iteration/detail/for_each.hpp:11,
from /home/meir/boost_1_59_0/boost/fusion/algorithm/iteration/for_each.hpp:12,
from /home/meir/boost_1_59_0/boost/fusion/include/for_each.hpp:11,
from temp.cpp:9:
/home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic_fwd.hpp:53:16: error: declaration of ‘struct boost::fusion::result_of::at<Node, mpl_::integral_c<int, 0> >’
struct at;
^
temp.cpp: In instantiation of ‘void print_visitor::operator()(Index, C&) [with Index = mpl_::integral_c<int, 0>; C = Node]’:
/home/meir/boost_1_59_0/boost/bind/bind.hpp:315:34: required from ‘void boost::_bi::list2<A1, A2>::operator()(boost::_bi::type<void>, F&, A&, int) [with F = print_visitor; A = boost::_bi::list1<mpl_::integral_c<int, 0>&>; A1 = boost::arg<1>; A2 = boost::reference_wrapper<Node>]’
/home/meir/boost_1_59_0/boost/bind/bind.hpp:907:50: required from ‘boost::_bi::bind_t<R, F, L>::result_type boost::_bi::bind_t<R, F, L>::operator()(A1&&) [with A1 = mpl_::integral_c<int, 0>&; R = void; F = print_visitor; L = boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> >; boost::_bi::bind_t<R, F, L>::result_type = void]’
/home/meir/boost_1_59_0/boost/mpl/for_each.hpp:78:25: required from ‘static void boost::mpl::aux::for_each_impl<false>::execute(Iterator*, LastIterator*, TransformFunc*, F) [with Iterator = boost::mpl::r_iter<mpl_::integral_c<int, 0> >; LastIterator = boost::mpl::r_iter<mpl_::integral_c<int, 1> >; TransformFunc = boost::mpl::identity<mpl_::na>; F = boost::_bi::bind_t<void, print_visitor, boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> > >]’
/home/meir/boost_1_59_0/boost/mpl/for_each.hpp:105:97: required from ‘void boost::mpl::for_each(F, Sequence*, TransformOp*) [with Sequence = boost::mpl::range_c<int, 0, 1>; TransformOp = boost::mpl::identity<mpl_::na>; F = boost::_bi::bind_t<void, print_visitor, boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> > >]’
/home/meir/boost_1_59_0/boost/mpl/for_each.hpp:118:48: required from ‘void boost::mpl::for_each(F, Sequence*) [with Sequence = boost::mpl::range_c<int, 0, 1>; F = boost::_bi::bind_t<void, print_visitor, boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> > >]’
temp.cpp:34:62: required from ‘void print_fields(C&) [with C = Node]’
temp.cpp:39:19: required from here
temp.cpp:26:48: error: no matching function for call to ‘at(Node&)’
<< boost::fusion::at<Index>(c) << std::endl;
^
temp.cpp:26:48: note: candidates are:
In file included from /home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic/begin.hpp:14:0,
from /home/meir/boost_1_59_0/boost/fusion/algorithm/iteration/detail/for_each.hpp:11,
from /home/meir/boost_1_59_0/boost/fusion/algorithm/iteration/for_each.hpp:12,
from /home/meir/boost_1_59_0/boost/fusion/include/for_each.hpp:11,
from temp.cpp:9:
/home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic_fwd.hpp:102:5: note: template<class N, class Sequence> constexpr typename boost::lazy_disable_if<boost::is_const<Sequence>, boost::fusion::result_of::at<Sequence, N> >::type boost::fusion::at(Sequence&)
at(Sequence& seq);
^
/home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic_fwd.hpp:102:5: note: substitution of deduced template arguments resulted in errors seen above
/home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic_fwd.hpp:107:5: note: template<class N, class Sequence> constexpr typename boost::fusion::result_of::at<const Sequence, N>::type boost::fusion::at(const Sequence&)
at(Sequence const& seq);
^
/home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic_fwd.hpp:107:5: note: template argument deduction/substitution failed:
/home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic_fwd.hpp: In substitution of ‘template<class N, class Sequence> constexpr typename boost::fusion::result_of::at<const Sequence, N>::type boost::fusion::at(const Sequence&) [with N = mpl_::integral_c<int, 0>; Sequence = Node]’:
temp.cpp:26:48: required from ‘void print_visitor::operator()(Index, C&) [with Index = mpl_::integral_c<int, 0>; C = Node]’
/home/meir/boost_1_59_0/boost/bind/bind.hpp:315:34: required from ‘void boost::_bi::list2<A1, A2>::operator()(boost::_bi::type<void>, F&, A&, int) [with F = print_visitor; A = boost::_bi::list1<mpl_::integral_c<int, 0>&>; A1 = boost::arg<1>; A2 = boost::reference_wrapper<Node>]’
/home/meir/boost_1_59_0/boost/bind/bind.hpp:907:50: required from ‘boost::_bi::bind_t<R, F, L>::result_type boost::_bi::bind_t<R, F, L>::operator()(A1&&) [with A1 = mpl_::integral_c<int, 0>&; R = void; F = print_visitor; L = boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> >; boost::_bi::bind_t<R, F, L>::result_type = void]’
/home/meir/boost_1_59_0/boost/mpl/for_each.hpp:78:25: required from ‘static void boost::mpl::aux::for_each_impl<false>::execute(Iterator*, LastIterator*, TransformFunc*, F) [with Iterator = boost::mpl::r_iter<mpl_::integral_c<int, 0> >; LastIterator = boost::mpl::r_iter<mpl_::integral_c<int, 1> >; TransformFunc = boost::mpl::identity<mpl_::na>; F = boost::_bi::bind_t<void, print_visitor, boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> > >]’
/home/meir/boost_1_59_0/boost/mpl/for_each.hpp:105:97: required from ‘void boost::mpl::for_each(F, Sequence*, TransformOp*) [with Sequence = boost::mpl::range_c<int, 0, 1>; TransformOp = boost::mpl::identity<mpl_::na>; F = boost::_bi::bind_t<void, print_visitor, boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> > >]’
/home/meir/boost_1_59_0/boost/mpl/for_each.hpp:118:48: required from ‘void boost::mpl::for_each(F, Sequence*) [with Sequence = boost::mpl::range_c<int, 0, 1>; F = boost::_bi::bind_t<void, print_visitor, boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> > >]’
temp.cpp:34:62: required from ‘void print_fields(C&) [with C = Node]’
temp.cpp:39:19: required from here
/home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic_fwd.hpp:107:5: error: invalid use of incomplete type ‘struct boost::fusion::result_of::at<const Node, mpl_::integral_c<int, 0> >’
/home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic_fwd.hpp:53:16: error: declaration of ‘struct boost::fusion::result_of::at<const Node, mpl_::integral_c<int, 0> >’
struct at;
^
make: *** [all] Error 1
Compilation exited abnormally with code 2 at Thu Dec 10 11:54:27
I found this post as I'm practicing the use of the MPL. I got here as I wanted to print the struct_member_name which you were successful at. The short answer is to include <boost/fusion/sequence.hpp>. fusion::at requires a sequence
BOOST_FUSION_ADAPT_STRUCT does only that, it does not create a sequence for the target. If you had have accessed the value in the same way you access the name, it would have worked.
boost::fusion::extension::access::struct_member<C, Index::value>::template apply<C>::call(x)
returns the value of interest. But of course, there is always a better way, that much code is pretty ugly. Once you have a sequence applied to your class, everything gets easier. Now, I didn't find a for_each that iterates and passes types, fusion::for_each dereferences the value and passes that to the functor. So I took some code from boost\fusion\sequence\io\out.hpp which moves across an iterator range.
This example prints the data your way, the iterator way, and directly using fusion's IO. I'm sure I'm missing a whole lot, but this is my first day of actually writing compile time code that works. Thanks for your question, I may not have gotten so far without it!
#include <iostream>
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/fusion/sequence.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
//https://www.boost.org/doc/libs/1_78_0/libs/fusion/doc/html/fusion/support/deduce_sequence.html
#include <boost/bind/bind.hpp>
#include <boost/fusion/iterator/distance.hpp>
struct test {
int val;
std::string name;
};
BOOST_FUSION_ADAPT_STRUCT(test,val,name)
//the origanal with changes
struct print_class
{
template <class Index, typename T>
void operator()(Index, T& x) const
{
std::cout << "from print_class: " << boost::fusion::extension::struct_member_name<T, Index::value>::call()
<< " = " << boost::fusion::at<Index>(x) << std::endl;
}
};
using namespace boost::placeholders;
template <class C> void print_fields(C& c) {
typedef boost::mpl::range_c<
int, 0, boost::fusion::result_of::size<C>::type::value> range;
boost::mpl::for_each<range>(
boost::bind<void>(print_class(), _1, boost::ref(c)));
}
//I could not find anything like this in the fusion namespace, so...
//T is a fusion iterator
namespace boost::fusion {
template <typename T>
auto get_name(){return boost::fusion::extension::struct_member_name<T::seq_type, T::index::value>::call();
}
}
//shamelessly stolen from fusion/io....
namespace {
using namespace boost;
namespace bf = fusion;
struct print_sequence_loop
{
template <typename OS, typename First, typename Last>
static void call(OS&, First&, Last&, mpl::true_)
{
}
template <typename OS, typename First, typename Last>
static void call(OS& os, First& first, Last& last, mpl::false_)
{
bf::result_of::equal_to<
typename bf::result_of::next<First>::type
, Last
>is_last;
//The code that prints
os << bf::get_name<First>() << " = ";
os << *first << std::endl;
//End the code that prints
call(os, fusion::next(first), last, is_last);
}
template <typename OS, typename First, typename Last>
static void call(OS& os, First const& first, Last const& last)
{
bf::result_of::equal_to<First, Last> eq;
call(os, first, last, eq);
}
};
template <typename OS, typename Sequence>
inline void print_sequence(OS& os, Sequence& seq)
{
print_sequence_loop::call(os, fusion::begin(seq), fusion::end(seq));
}
}
using boost::fusion::operators::operator<<;
int main() {
test the_test{ 12,"this is me" };
print_sequence(std::cout, the_test);
std::cout << '\n';
print_fields(the_test);
std::cout << "\n\n this is using fusions OS\n";
std::cout << the_test << std::endl;
}
GCC demo And it works with MSVC.

Binding member functions with 'boost::optional' argument with boost::spirit

I have the following grammar
template <typename Iterator>
struct Grammar : boost::spirit::qi::grammar<Iterator, void(), boost::spirit::ascii::space_type>
{
VariableMap variables;
bool ret;
Grammar(const VariableMap &variables) : Grammar::base_type(start), variables(variables), ret(true)
{
using boost::spirit::qi::lit;
using boost::spirit::qi::lexeme;
using boost::spirit::qi::char_;
using boost::spirit::ascii::alnum;
using boost::spirit::ascii::string;
using namespace boost::spirit::qi::labels;
using boost::spirit::qi::_1;
using boost::spirit::qi::_2;
using boost::phoenix::bind;
key %= char_("a-zA-Z_") >> *char_("a-zA-Z_0-9");
value %= +char_("a-zA-Z_0-9");
pair = (key >> -("=" >> value)) [ bind(&Grammar<Iterator>::check, this, _1, _2) ];
start = pair % ',';
}
void check(const std::string &key, const boost::optional<std::string> &value)
{
// ...
}
boost::spirit::qi::rule<Iterator, std::string(), boost::spirit::ascii::space_type> key, value;
boost::spirit::qi::rule<Iterator, void(), boost::spirit::ascii::space_type> pair;
boost::spirit::qi::rule<Iterator, void(), boost::spirit::ascii::space_type> start;
};
When the '"=" >> value' part is not optional, and the signature of 'check' is just 'void(const std::string&, const std::string&)' it compiles. But making that part optional, and adjusting the signature accordingly, these error messages appear:
In instantiation of ‘py::com::personal::builder::Grammar<Iterator>::Grammar(const VariableMap&) [with Iterator = const char*; py::com::personal::builder::VariableMap = std::map<std::basic_string<char>, std::basic_string<char> >]’:
../../../../py.com.personal/builder/TaskLoader.cpp:537:47: required from here
../../../../py.com.personal/builder/TaskLoader.cpp:511:13: error: call of overloaded ‘bind(void (py::com::personal::builder::Grammar<const char*>::*)(const string&, const boost::optional<std::basic_string<char> >&), py::com::personal::builder::Grammar<const char*>* const, const _1_type&, const _2_type&)’ is ambiguous
../../../../py.com.personal/builder/TaskLoader.cpp:511:13: note: candidates are:
In file included from /home/gimenero/applib/boost/include/1.55/boost/preprocessor/iteration/detail/iter/forward1.hpp:57:0,
from /home/gimenero/applib/boost/include/1.55/boost/spirit/home/phoenix/bind/detail/bind_member_function.hpp:20,
from /home/gimenero/applib/boost/include/1.55/boost/spirit/home/phoenix/bind/bind_member_function.hpp:74,
from ../../../../py.com.personal/builder/TaskLoader.cpp:18:
/home/gimenero/applib/boost/include/1.55/boost/spirit/home/phoenix/bind/detail/bind_member_function.hpp:45:5: note: boost::phoenix::actor<typename boost::phoenix::as_composite<boost::phoenix::detail::function_eval<3>, boost::phoenix::detail::member_function_ptr<2, RT, RT (ClassT::*)(T0, T1)>, ClassA, A0, A1>::type> boost::phoenix::bind(RT (ClassT::*)(T0, T1), const ClassA&, const A0&, const A1&) [with RT = void; ClassT = py::com::personal::builder::Grammar<const char*>; T0 = const std::basic_string<char>&; T1 = const boost::optional<std::basic_string<char> >&; ClassA = py::com::personal::builder::Grammar<const char*>*; A0 = boost::phoenix::actor<boost::spirit::argument<0> >; A1 = boost::phoenix::actor<boost::spirit::argument<1> >; typename boost::phoenix::as_composite<boost::phoenix::detail::function_eval<3>, boost::phoenix::detail::member_function_ptr<2, RT, RT (ClassT::*)(T0, T1)>, ClassA, A0, A1>::type = boost::phoenix::composite<boost::phoenix::detail::function_eval<3>, boost::fusion::vector<boost::phoenix::value<boost::phoenix::detail::member_function_ptr<2, void, void (py::com::personal::builder::Grammar<const char*>::*)(const std::basic_string<char>&, const boost::optional<std::basic_string<char> >&)> >, boost::phoenix::value<py::com::personal::builder::Grammar<const char*>*>, boost::spirit::argument<0>, boost::spirit::argument<1>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >]
In file included from /home/gimenero/applib/boost/include/1.55/boost/bind/bind.hpp:1595:0,
from /home/gimenero/applib/boost/include/1.55/boost/bind.hpp:22,
from ../../../../py.com.personal/builder/TaskLoader.cpp:24:
/home/gimenero/applib/boost/include/1.55/boost/bind/bind_mf_cc.hpp:67:5: note: boost::_bi::bind_t<R, boost::_mfi::mf2<R, T, B1, B2>, typename boost::_bi::list_av_3<A1, A2, A3>::type> boost::bind(R (T::*)(B1, B2), A1, A2, A3) [with R = void; T = py::com::personal::builder::Grammar<const char*>; B1 = const std::basic_string<char>&; B2 = const boost::optional<std::basic_string<char> >&; A1 = py::com::personal::builder::Grammar<const char*>*; A2 = boost::phoenix::actor<boost::spirit::argument<0> >; A3 = boost::phoenix::actor<boost::spirit::argument<1> >; typename boost::_bi::list_av_3<A1, A2, A3>::type = boost::_bi::list3<boost::_bi::value<py::com::personal::builder::Grammar<const char*>*>, boost::_bi::value<boost::phoenix::actor<boost::spirit::argument<0> > >, boost::_bi::value<boost::phoenix::actor<boost::spirit::argument<1> > > >]
In file included from /home/gimenero/applib/boost/include/1.55/boost/bind.hpp:22:0,
from ../../../../py.com.personal/builder/TaskLoader.cpp:24:
/home/gimenero/applib/boost/include/1.55/boost/bind/bind.hpp:1488:5: note: boost::_bi::bind_t<boost::_bi::unspecified, F, typename boost::_bi::list_av_3<A1, A2, A3>::type> boost::bind(F, A1, A2, A3) [with F = void (py::com::personal::builder::Grammar<const char*>::*)(const std::basic_string<char>&, const boost::optional<std::basic_string<char> >&); A1 = py::com::personal::builder::Grammar<const char*>*; A2 = boost::phoenix::actor<boost::spirit::argument<0> >; A3 = boost::phoenix::actor<boost::spirit::argument<1> >; typename boost::_bi::list_av_3<A1, A2, A3>::type = boost::_bi::list3<boost::_bi::value<py::com::personal::builder::Grammar<const char*>*>, boost::_bi::value<boost::phoenix::actor<boost::spirit::argument<0> > >, boost::_bi::value<boost::phoenix::actor<boost::spirit::argument<1> > > >]
gmake[2]: *** [build/Debug/GNU-Linux-x86/_ext/652184350/TaskLoader.o] Error 1
Im using gcc 4.7.2.
It was an Address-Dependent-Lookup issue (boost::phoenix::bind vs boost::bind), as pointed out by 'cv_and_he' (he did not want yo make the answer). Overlooked the errors too fast.