I have a problem when invoking nested std::bind expressions. The following code demonstrates the problem. It fails to compile with libc++, but works with boost:
#define BOOST 0
#if BOOST
#include <boost/function.hpp>
#include <boost/bind.hpp>
using boost::function;
using boost::bind;
#else
#include <functional>
using std::function;
using std::bind;
using std::placeholders::_1;
#endif
int sum(int a, int b) { return a+b; }
// works
template <typename F>
int yeah(F f, int c)
{
return f(c);
}
// breaks with libc++
template <typename F>
int nope(F f, int c)
{
return bind(f, c)();
}
// fixes the problem
template <typename F>
int fix1(F f, int c)
{
function<int(int)> g = f;
return bind(g, c)();
}
template <typename F>
class protect_t
{
public:
typedef typename F::result_type result_type;
explicit protect_t(F f): f_(f) {}
template <typename... Args>
result_type operator()(Args&&... args)
{
return f_(std::forward<Args>(args)...);
}
private:
F f_;
};
template <typename F>
protect_t<F> protect(F f)
{
return protect_t<F>(f);
}
// compilation fails with libc++
template <typename F>
int fix2(F f, int c)
{
return bind(protect(f), c)();
// F copy(f); // fails due to this!
}
#include <iostream>
int main()
{
std::cout << yeah(bind(sum, _1, 4), 5) << std::endl; // works
std::cout << nope(bind(sum, _1, 4), 5) << std::endl; // breaks
std::cout << fix1(bind(sum, _1, 4), 5) << std::endl; // fixes
std::cout << fix2(bind(sum, _1, 4), 5) << std::endl; // doesn't compile
}
Wrapping the bind expression in a std::function (see fix1) remedies the problem, albeit by sacrificing speed due to run-time polymorphism disabling inlining (haven't measured it though).
Wrapping the bind expression in protect_t (see fix2) is inspired by boost::protect, however, compilation with libc++ fails due to bind expressions not being copyable. Which makes me wonder why wrapping them in std::function works anyway.
Any idea how to solve this problem? What's wring with std::bind anyway? First I thought the problem is related to eager evaluation of bind expressions dictated by the C++11 standard (see here), but that would not be a problem here, would it?
The standard says that any callable can be wrapped using std::bind, including those produced by a preceding call to std::bind. Your problem is caused by a deficiency in the implementation of the standard library you're using, the solution is either to upgrade or, if this bug isn't still fixed, to switch to a different implementation.
Related
I discovered what appears to be a mind breaking bug in the 3 compilers from the title. The following code compiles with the latest versions of all three compilers using both the c++11 and c++14 standards, even though it really shouldn't as the "visit_detail" function is not visible to "main".
Correction: I was stupid, not actually a bug in GCC/Clang, seems to be a bug in my MSVC version tho.
#include <utility>
#include <iostream>
#include <type_traits>
namespace bug
{
using namespace std;
using size_t = unsigned long long;
namespace detail
{
struct visit_stop_t {};
constexpr bug::detail::visit_stop_t visit_stop = bug::detail::visit_stop_t();
template <typename Visitor, typename First, typename... Tail>
void visit_detail(Visitor&& vis, First&& first, Tail&&... tail)
{
// code, not necessairy to recreate bug
}
}
template <typename Visitor, typename... Variants>
void visit(Visitor&& vis, Variants&&... vars)
{
bug::detail::visit_detail(bug::forward<Visitor>(vis), bug::forward<Variants>(vars)..., bug::detail::visit_stop);
}
template <typename Visitor>
void visit(Visitor&& vis) = delete;
}
using namespace bug;
// dummy variant, used to test the code
// code is never actually used in this version
template <typename... T>
struct variant
{
static constexpr bug::size_t size() noexcept { return sizeof...(T); }
constexpr variant(int) noexcept {}
template <bug::size_t I>
constexpr int get() const noexcept { return 5; }
};
// simple example visitor
// code is never actually used in this version
struct visitor
{
int operator()(int x) { std::cout << x << std::endl; return x; }
double operator()(double x) { std::cout << x << std::endl; return x; }
};
int main()
{
visitor vis;
variant<int, double> var = 5;
// where the trouble is:
visit_detail(vis, var, bug::detail::visit_stop); // ADL: http://en.cppreference.com/w/cpp/language/adl
visit_detail(vis, var); // fails with GCC/Clang, no error with MSVC => MSVC bug maybe
std::cout << "Press enter to continue . . . ";
std::getchar();
return 0;
}
What you're experiencing is a C++ feature called argument-dependent lookup, or ADL for short. Basically, if you invoke a function f without explicitly qualifying it, the compiler will look for f in the namespaces of the arguments that you've passed.
This is what allows operator<< for IO streams to work without requiring qualifications:
std::cout << 100; // finds std::operator<<(std::ostream&, int);
In your particular case, the argument bug::detail::visit_stop is making the compiler look for visit_detail inside the bug::detail namespace.
I've written the following (relatively) simple implementation of a std::tuple zip function (analogous to Python's zip) with perfect forwarding:
template <size_t I, size_t N>
struct tuple_zip_helper {
template <typename... Tuples>
constexpr auto operator()(Tuples&&... tuples) const {
return tuple_cat(
make_tuple( forward_as_tuple(get<I>(forward<Tuples>(tuples))...) ),
tuple_zip_helper<I+1, N>()(forward<Tuples>(tuples)...)
);
}
};
template <size_t N>
struct tuple_zip_helper<N, N> {
template <typename... Tuples>
constexpr auto operator()(Tuples&&...) const {
return forward_as_tuple();
}
};
namespace std {
// Extend min to handle single argument case, for generality
template <typename T>
constexpr decltype(auto) min(T&& val) { return forward<T>(val); }
}
template <typename... Tuples>
auto tuple_zip(Tuples&&... tuples) {
static constexpr size_t min_size = min(tuple_size<decay_t<Tuples>>::value...);
return tuple_zip_helper<0, min_size>()( forward<Tuples>(tuples)... );
}
This appears to work fine for two or more tuples, even when mixing lvalues and rvalues and even when I use a BlabberMouth class to check for spurious copies and moves:
template <typename Tuple>
void f(Tuple&& tup) {
cout << get<0>(get<0>(tup)).data << endl;
}
struct Blabbermouth {
Blabbermouth(string const& str) : data(str) { }
Blabbermouth(Blabbermouth const& other) : data(other.data) { cout << data << " copied" << endl; }
Blabbermouth(Blabbermouth&& other) : data(move(other.data)) { cout << data << " moved" << endl; }
string data;
};
int main(int argc, char** argv) {
Blabbermouth x("hello ");
// prints "hello"
f(tuple_zip(
forward_as_tuple(x, 2),
forward_as_tuple(Blabbermouth("world"), 3)
));
}
It also works fine when I give it just one tuple without mixing lvalues and rvalues (clang-3.9, earlier versions of clang choke on this as well):
f(tuple_zip( forward_as_tuple(Blabbermouth("world"), 3) )); // prints "world"
However, when I mix lvalues and rvalues and only give one tuple, clang freaks out about something in a noexecpt specification (but gcc is fine, and even runs correctly):
auto x = BlabberMouth("hello");
f(tuple_zip( forward_as_tuple(x, 3) )); // clang freaks out, gcc okay
Live Demo
What (if anything) am I doing wrong? Should gcc be complaining, or should clang not be complaining? Does my code have any dangling references that I'm just "getting lucky" with, and that's why clang is objecting? Should I have done this differently? If clang is the one wrong here, can anyone suggest a workaround? (And/or link me to a bug report?)
Update
#Oktalist contributed a much more minimal example that illustrates the same problem:
struct foo {};
int main(int argc, char** argv)
{
foo f;
std::tuple<foo&> t(f);
std::tuple_cat(std::make_tuple(t), std::make_tuple());
}
(I had considered making my example more minimal as well, but I wasn't sure if what I was doing was exactly analogous to this, mainly because I don't fully understand how perfect forwarding interacts with auto/decltype(auto) return values, return value optimization (RVO), std::get and std::make_tuple, so I wanted to be sure I wasn't doing something else stupid.)
The bug is caused by the calls to tuple_cat (though not exactly in it; it seems to be some messiness inside libc++'s tuple's byzantine maze of constructors and SFINAE conditions), so the workaround is to avoid using it.
There is no point in doing recursive tuple_cats anyway; one pack expansion (or two) will do.
template<size_t I, typename... Tuples>
constexpr auto tuple_zip_one(Tuples&&... tuples) {
return forward_as_tuple(get<I>(forward<Tuples>(tuples))...);
}
template<size_t...Is, typename... Tuples>
constexpr auto tuple_zip_helper(index_sequence<Is...>, Tuples&&... tuples) {
return make_tuple(tuple_zip_one<Is>(forward<Tuples>(tuples)...)...);
}
template <typename... Tuples>
auto tuple_zip(Tuples&&... tuples) {
static constexpr size_t min_size = min({tuple_size<decay_t<Tuples>>::value...});
return tuple_zip_helper( make_index_sequence<min_size>(), forward<Tuples>(tuples)... );
}
I took the liberty of removing your UB-inducing min overload and simply using the standard initializer_list version instead.
Demo.
Given a callable object ( a function ) a, and an argument b ( or a series of arguments ), I would like to deduce the type returned from f considering that f is overloaded with multiple signatures.
one of my many attempts is
#include <iostream>
#include <cstdint>
#include <string>
#include <functional>
#include <utility>
#include <typeinfo>
int foo(uint32_t a) { return ((a + 0) * 2); }
bool foo(std::string a) { return (a.empty()); }
/*template <typename A, typename B> auto bar(A a, B b) -> decltype(a(b)) {
return (a(b));
}*/
/*template <typename A, typename B> decltype(std::declval<a(b)>()) bar(A a, B b)
{
return (a(b));
}*/
template <typename A, typename B> void bar(std::function<A(B)> a, B b) {
std::cout << a(b) << "\n";
}
int main() {
// the following 2 lines are trivial and they are working as expected
std::cout << foo(33) << "\n";
std::cout << typeid(decltype(foo(std::string("nothing")))).name() << "\n";
std::cout << bar(foo, 33) << "\n";
//std::cout << bar(foo, std::string("Heinz")) << "\n";
return (0);
}
and 2 templates options are commented out and included in the previous code.
I'm using declval result_of auto decltype without any luck.
How does the overloading resolution process works at compile time ?
If anyone wants to know why I'm trying to get creative with this, is that I'm trying to implement some Currying in C++11 in a workable/neat way.
The problem is that you can't easily create a function object from an overload set: when you state foo or &foo (the function decays into a function pointer in most case, I think) you don't get an object but you get an overload set. You can tell the compiler which overload you want by either calling it or providing its signature. As far as I can tell, you don't want either.
The only approach I'm aware of is to turn your function into an actual function object which makes the problem go away:
struct foo_object
{
template <typename... Args>
auto operator()(Args&&... args) -> decltype(foo(std::forward<Args>(args)...)) {
return foo(std::forward<Args>(args)...);
}
};
With that wrapper which is unfortunately needed for each name, you can trivially deduce the return type, e.g.:
template <typename Func, typename... Args>
auto bar(Func func, Args&&... args) -> decltype(func(std::forward<Args>(args)...)) {
// do something interesting
return func(std::forward<Args>(args)...);
}
int main() {
bar(foo_object(), 17);
bar(foo_object(), "hello");
}
It doesn't quite solve the problem of dealing with overload sets but it gets reasonably close. I experimented with this idea, essentially also for the purpose of currying in the context of an improved system of standard library algorithms and I'm leaning towards the algorithms actually being function objects rather than functions (this is desirable for various other reasons, too; e.g., you don't need to faff about when you want to customize on algorithm with another one).
If foo is overloaded, you need to use the following:
#include <type_traits>
int foo(int);
float foo(float);
int main() {
static_assert(std::is_same<decltype(foo(std::declval<int>())), int>::value, "Nope.");
static_assert(std::is_same<decltype(foo(std::declval<float>())), float>::value, "Nope2.");
}
If it's not, then this will suffice:
#include <type_traits>
bool bar(int);
int main() {
static_assert(std::is_same<std::result_of<decltype(bar)&(int)>::type, bool>::value, "Nope3.");
}
Yes, it is verbose because you're trying to explicitly extract what implicit ad-hoc overloading does for you.
This is actually already implemented for you std::result_of. Here is a possible implementation
template<class>
struct result_of;
// C++11 implementation, does not satisfy C++14 requirements
template<class F, class... ArgTypes>
struct result_of<F(ArgTypes...)>
{
typedef decltype(
std::declval<F>()(std::declval<ArgTypes>()...)
) type;
};
Suppose I want to have a function double adapter(double), is there a general way to compose it with a boost::function<double(...)> functor to produce another boost::function<double(...)> functor2 where functor2(...) == adapter(functor(...))? In particular, it would be cool if there was a way to do this without using C++11.
edit To clarify, I'm interested in knowing if there's a way to write something that can handle any boost::function<double(...)>, i.e. ones that have different length signatures without having to copy and paste multiple times for 1, 2, 3, etc. arguments.
Without c++11, there are a significant number of complexities, including the varadic arguments and forwarding.
With C++11, it can be done, mostly by specializaing std::is_bind_expression. When this function object is used in a bind, it calls the function object that was stored with all of the arguments that were provided during the call to the bound function object. Note, this works with any function object, not just std::function.
This works with GCC 4.7.
#include <functional>
#include <utility>
#include <type_traits>
namespace detail
{
template<typename Func>
struct compose_functor
{
Func f;
explicit compose_functor(const Func& f) : f(f) {};
template<typename... Args>
auto operator()(Args&&... args) const -> decltype(f(std::forward<Args>(args)...))
{
return f(std::forward<Args>(args)...);
}
};
}
template<typename Func>
detail::compose_functor
<Func> compose(Func f)
{
return detail::compose_functor<Func>(f);
}
namespace std
{
template<typename T>
struct is_bind_expression< detail::compose_functor<T> > : true_type {};
}
#include <numeric>
int adapter(double d)
{
return (int)d;
}
int main()
{
std::function<int(double)> f1 = std::bind(adapter, compose(std::negate<double>()));
std::function<int(double, double)> f2 = std::bind(adapter, compose(std::plus<double>()));
// 1.5 -> -1.5 -> -1
std::cout << f1(1.5) << std::endl;
// 2.3+4.5 = 6.8 -> 6
std::cout << f2(2.3, 4.5) << std::endl;
}
Is there any function objects in the boost that are generic equivalents to the std::equal_to, std::greater etc. family of function objects?
Essentially, std::equal_to should become something like
struct generic_equal_to
{
template <class T, class U>
bool operator()(const T& t, const U& u) const
{
return t == u;
}
};
I can see how the generic versions of std::plus etc. might be trickier due to issues with the return type (though the decltype can solve that). I can't see any possible reason why the std::equal_to function object itself should require a template argument, though.
Surely somewhere in boost or in the STL these versions exist? They are, of course, trivial to write, but I very much dislike duplicating library code, especially for something as apparently trivial as this.
EDIT:
As some context as to why I would want this instead of using lambdas, or another function-object generation method:
I was writing a generic boost::fusion sequence comparison function thusly:
template <class T>
bool sequence_equal(const T& left, const T& right)
{
return fusion::all(
fusion::zip(left, right),
fusion::fused<generic_equal_to>());
}
Note the fusion::fused<generic_equal_to> part, which leads to the isse that you can't practically specify a boost::lambda or boost::phoenix function-object by type. I guess one solution might be decltype:
fusion::fused<decltype(_1 == _2)>()
That seems very awkward though, and might not even work, depending on how boost::lambda or boost::phoenix is implemented - I'm really not sure.
I know you can use fusion::make_fused to get around this whole issue, but then you have to instantiate the function object. The solution I thought of, then, would be a non-template equal_to struct - I called mine generic_equal_to.
I know it's a very trivial problem - after all, make_fused(_1 == _2) will probably inline down to much the same assembly as fused<generic_equal_to>. I just couldn't believe that there was no generic_equal_to function object in boost or in the STL anywhere, hence this question.
I don't think there's anything quite as direct as you're asking for, but there are utilities that not only cover your use-cases, but go beyond. They are Boost.Lambda and Boost.Phoenix (the latter being a more generic successor to the lambda library).
Example using Boost.Lambda for generic equality:
#include <boost/lambda/lambda.hpp>
#include <iomanip>
#include <iostream>
struct foo {};
bool operator==(foo, foo) { return true; }
bool operator==(foo, int) { return false; }
template <typename T, typename U, typename Func>
void f(const T& x, const U& y, Func func)
{
std::cout << func(x, y) << std::endl;
}
int main()
{
using namespace boost::lambda; // for placeholders
std::cout << std::boolalpha;
foo a, b;
int i = 0;
f(a, b, _1 == _2);
f(a, i, _1 == _2);
}
And the same, with Phoenix:
#include <boost/phoenix.hpp>
#include <iomanip>
#include <iostream>
struct foo {};
bool operator==(foo, foo) { return true; }
bool operator==(foo, int) { return false; }
template <typename T, typename U, typename Func>
void f(const T& x, const U& y, Func func)
{
std::cout << func(x, y) << std::endl;
}
int main()
{
using namespace boost::phoenix::arg_names; // for placeholders
std::cout << std::boolalpha;
foo a, b;
int i = 0;
f(a, b, arg1 == arg2);
f(a, i, arg1 == arg2);
}
Each of these can be extended to support the other operators in the obvious way (and more generally, into other expressions). I would personally go with Phoenix, because if you find out you need more functionality than lambda offers you won't end up including both.
Now in C++14 there is std::equal_to<void> (that can be also used as std::equal_to<>)
std::equal_to<> is a specialization of std::equal_to with parameter and return type deduced.
template< class T, class U>
constexpr auto operator()( T&& lhs, U&& rhs ) const
-> decltype(std::forward<T>(lhs) == std::forward<U>(rhs));
Returns the result of equality comparison between lhs and rhs.
Docs