std::bind with template member function - templates

I have a strange problem that I cannot bind this template member function,
all this code compiles: http://ideone.com/wl5hS8
It's a simple code: I have a ExecutionList which should hold callable functions in a std::vector. I can now add functions by calling ExecutionList::addFunctor. But there, I cannot bind to template<typename T> void Functor::calculate(T * t). I am asking me why, what is missing here, the compiler cannot somehow deduce what I have written in
m_calculationList.push_back( std::bind(&T::calculate<Type>, extForce, std::placeholders::_1 ) );
*Error: *
error: expected primary-expression before ‘>’ token
m_calculationList.push_back( std::bind(T::calculate<Type>, extForce, std::placeholders::_1 ) );
^
The Code:
#include <functional>
#include <iostream>
#include <vector>
struct MyType{
static int a;
int m_a;
MyType(){a++; m_a = a;}
void print(){
std::cout << "MyType: " << a << std::endl;
}
};
int MyType::a=0;
struct Functor{
static int a;
int m_a;
Functor(){a++; m_a = a;}
// Binding this function does not work
template<typename T>
void calculate(T * t){}
// Binding this function works!!!
void calculate2(MyType * t){
std::cout << " Functor: " << m_a <<std::endl;
t->print();
}
};
int Functor::a=0;
// Binding this function works!!!
template<typename T>
void foo( T * t){}
class ExecutionList{
public:
typedef MyType Type;
template<typename T>
void addFunctor(T * extForce){
//m_calculationList.push_back( std::bind(&T::calculate<Type>, extForce, std::placeholders::_1 ) ); /// THIS DOES NOT WORK
m_calculationList.push_back( std::bind(&T::calculate2, extForce, std::placeholders::_1 ) );
m_calculationList.push_back( std::bind(&foo<Type>, std::placeholders::_1 ) );
}
void calculate(Type * t){
for(auto it = m_calculationList.begin(); it != m_calculationList.end();it++){
(*it)(t); // Apply calculation function!
}
}
private:
std::vector< std::function<void (Type *)> > m_calculationList;
};
int main(){
MyType b;
ExecutionList list;
list.addFunctor(new Functor());
list.addFunctor(new Functor());
list.calculate(&b);
}

Looks like you're missing the template keyword. If T is a template parameter and T::calculate refers to a template you need to tell the compiler that calculate is a template and not some static variable which you try to compare using the less-than operator with something else:
T::template calculate<Type>
I ran into the exact same problem a couple of years ago but today (post C++11) I would probably solve it with a lambda which is simpler:
std::function<void(Type*)> func = [obj](Type*param){obj.calculate(param);};
Anyhow, try to reduce the number of new uses. Look for a better way to manage your resources. Your code seems to leak a couple of functors.

Related

bind with enable_if'd member functions

I'm getting tripped up on calling bind on an enable_if'd member function. I've worked around it using if constexpr, but I'm curious what the solution would be for this issue. The code is the simplest reproducer and not representative of the overarching problem I'm trying to solve. How can I make this work?
#include <iostream>
#include <type_traits>
#include <functional>
template <typename T>
class test {
public:
template <typename U = T>
typename std::enable_if<std::is_copy_constructible<U>::value, void>::type
foo(const T& v){
std::cout << "copy constructible";
}
template <typename U = T>
typename std::enable_if<!std::is_copy_constructible<U>::value, void>::type
foo(const T& v){
std::cout << "not copy constructible";
}
void foo_bar(const T& v){
std::cout << "test";
}
};
int main(int argn, char** argc){
test<int> myfoo;
myfoo.foo(3); //Works
auto func = std::bind(&test<int>::foo_bar, &myfoo, 3); //Works
auto func = std::bind(&test<int>::foo, &myfoo, 3); //Doesn't work
func();
return 0;
}
The problem is that U is substituted only when the member function template foo is actually called, and not when it is used inside of std::bind(). This means that when specifying &test<int>::foo inside bind(), it isn't known which of the two member function templates is going to be actually instantiated since the instantiation of definition will happen when we actually call foo(), and so the compiler can't decide which of them you're referring to. This is exactly what <unresolved overloaded function type> means in the error that you're getting:
no matching function for call to 'bind(<unresolved overloaded function type>, test<int>*, int)'
32 | auto func2 = std::bind(&test<int>::foo, &myfoo, 3); //Doesn't work
| ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can solve this by either specifying U explicitly, like:
&test<int>::foo<int>
or by using a lambda, like:
auto func = [&myfoo]() { myfoo.foo(3); };
There is a third way to solve this in C++20 using requires-clause as shown below. Note that the below program is well-formed but gcc and msvc incorrectly rejects it. Only clang accepts it which is the correct behavior. Demo
#include <iostream>
#include <type_traits>
#include <functional>
template <typename T>
class test {
public:
void foo(const T& v) requires std::is_copy_constructible_v<T>{
std::cout << "copy constructible";
}
void foo(const T& v) requires (!std::is_copy_constructible_v<T>) {
std::cout << "non copy constructible";
}
void foo_bar(const T& v){
std::cout << "test";
}
};
int main(int argn, char** argc){
test<int> myfoo;
myfoo.foo(3); //Works
auto func = std::bind(&test<int>::foo_bar, &myfoo, 3); //Works
auto func2 = std::bind(&test<int>::foo, &myfoo, 3); //works
func();
func2();
}

Is there a way to match a nested template type implicitly in C++?

I have the following MWE:
#include <iostream>
#include <memory>
class A {
public:
int n = 42;
typedef std::shared_ptr<A> Ptr;
};
template<typename T>
void foo(typename T::Ptr arg) {
std::cout << arg->n << std::endl;
}
template<typename T>
void bar(T arg) {
std::cout << arg.n << std::endl;
}
int main() {
A::Ptr a = A::Ptr(new A());
foo<A>(a); // Can I avoid giving <A> here explicitly.
// foo(a); // does not compile
bar(*a); // after all this does work
return 0;
}
To me it looks like it should also be possible to call foo(a) instead of foo<A>(a). Why is this not possible and can I somehow change the definition of foo to make this possible?
I realize that I could just skip the ::Ptr in the signature, but I still want to have access to the A type without the pointer.
That is not possible because that is non-deducible context.
The type of a is just std::shared_ptr<A>, which means if foo(a) works, then the following should also work:
std::shared_ptr<A> x(new A());
foo(x);
If so, then what should T be deduced to — and why? You might be tempted to say "T should be deduced to A, because A has a nested type Ptr which is same as std::shared_ptr<A>". Well, what if there is another class defined as:
struct B
{
typedef std::shared_ptr<A> Ptr;
};
What should T be deduced to? A or B? or something else?
Here is another topic that discusses non-deducible context using a different example:
C++, template argument can not be deduced
Hope that helps.
Nawaz's answer has explained why the code doesn't work, I'll focus on this question:
but I still want to have access to the A type without the pointer.
std::shared_ptr has a member type element_type, you could use it like typename T::element_type. And if you want the code works well with raw pointer too, you could provide a trait class template:
template <typename T>
struct trait_element_type {
using element_type = std::remove_pointer_t<T>;
};
template <typename T>
struct trait_element_type<std::shared_ptr<T>> {
using element_type = T;
};
And then use it as:
template<typename T>
void foo(T arg) {
std::cout << arg->n << std::endl;
typename trait_element_type<T>::element_type x; // retrieve the element type
std::cout << x.n << std::endl;
}
LIVE

Is there in iso or boost function pointer that has the same syntax as std::function

I was wondering if there is a lightweight version of std::function that works only for function pointers but doesnt have horrible :) syntax like regular function pointers.
Aka something like this:
int square(int x)
{
return x*x;
}
//...
function_ptr<int (int)> = square;
Ofc bind and all other fancy stuff std::function supports will fail, but I am ok with that, if I need std::function I will use it.
What you are asking for is for a template to tranform from signature to pointer to function to signature, that is, to add a pointer to the type. That is already done in the standard library:
std::add_pointer<X>::type
But since what you want is the nicer syntax, you can add a template alias:
template <typename T>
using ptr = typename std::add_pointer<T>::type;
Then you can use it directly in your container:
void f(int);
std::vector<ptr<void (int)>> v; // vector of pointers to functions taking `int`
v.push_back(&f);
Depending on the context you want to use this in, it could be as simple as auto and/or decltype:
#include <iostream>
int main()
{
auto f = square;
std::cout << f(5) << std::endl;
// define a type
using F = decltype(&square);
F g = square;
std::cout << g(5) << std::endl;
}
You can write an opaque wrapper if you do not want to use typedef directly. A prototype implementation using variadic templates is as follows. The same technique can be extended to other callable objects such as lambdas.
#include <iostream>
template<typename T>
struct function_ptr {};
template<class R, class... Args>
struct function_ptr<R(Args...)>{
typedef R (*funcType)(Args...);
function_ptr(funcType f) : _f(f) {}
funcType _f;
R operator()(Args... args) { return _f(args...);}
};
int square(int x) {
return x*x;
}
int main() {
function_ptr<int (int)> f = square;
std::cout << f(2) << std::endl;
}

ScopedExit implementation: pass arguments to the function object

I'm trying to implement simple ScopedExit class. Here's the code:
#include <iostream>
#include <functional>
template<class R, class... Args>
class ScopedExit
{
public:
ScopedExit(std::function<R(Args...)> exitFunction)
{
exitFunc_ = exitFunction;
}
~ScopedExit()
{
exitFunc_();
}
private:
std::function<R(Args...)> exitFunc_;
};
template<>
class ScopedExit<void>
{
public:
ScopedExit(std::function<void ()> exitFunction)
{
exitFunc_ = exitFunction;
}
~ScopedExit()
{
exitFunc_();
}
private:
std::function<void ()> exitFunc_;
};
void foo()
{
std::cout << "foo() called\n";
}
class Bar
{
public:
void BarExitFunc(int x, int y)
{
std::cout << "BarExitFunc called with x =" << x << "y = " << y << "\n";
}
};
int main()
{
Bar b;
std::cout << "Register scoped exit func\n";
{
ScopedExit<void, int, int> exitGuardInner(std::bind(&Bar::BarExitFunc, &b, 18, 11));
}
ScopedExit exitGuardOutter(foo);
std::cout << "About to exit from the scope\n";
return 0;
}
So, there are a couple of questions:
How to pass exit's function arguments to it? For example, I bind BarExitFunc with two integer arguments: 18 and 11. So how can I pass it to the exitFunc_ in the destructor? I think I need something like invoke function with std::forward<>.
gcc 4.7.2 (from ideone.com) complains about exitGuardOutter. It says:
prog.cpp:60:16: error: missing template arguments before ‘exitGuardOutter’
prog.cpp:60:16: error: expected ‘;’ before ‘exitGuardOutter’
Thanks in advance.
How to pass exit's function arguments to it? For example, I bind BarExitFunc with two integer arguments: 18 and 11. So how can I pass it to the exitFunc_ in the destructor?
I can see no reason whatsoever to pass arguments to exitFunc_ at call time in the destructor. Whatever you do, you'll have to provide those arguments upfront in the ScopedExit constructor anyway.
The most straightforward way is simply to use a function<R()> and bind any required arguments at the definition site like you're already doing:
ScopedExit<R> guard(std::bind(someFunction, someArg, otherArg));
This allows you to get rid of the variadic template arguments altogether and simplifies your template a lot.
Now, if what is bothering you is that you have to type std::bind and you would rather use such a syntax:
ScopedExit<R> guard(someFunction, someArg, otherArg);
Really, I don't see the point since it makes the template more complicated, but why not... Just bind/forward the arguments in the constructor itself and still store a function<R()>:
template<typename... Args>
ScopedExit(std::function<R(Args...)> exitFunction, Args&&... args)
{
exitFunc_ = std::bind(exitFunction, std::forward<Args>(args)...);
}
Now you systematically bind the function even if there are no arguments to bind, so you may want to specialize your class to avoid this useless bind when there are no arguments. This is left as an exercise.
gcc 4.7.2 (from ideone.com) complains about exitGuardOutter
This is because foo isn't a std::function and the compiler can't deduce the correct template arguments. As already mentioned by #ForEveR you could just define your guard variable as ScopedExit<void> guard(foo);.
Or, wrapping it all up and keeping in mind what I first said (bind is best left out of your template and used at the definition site of your guard) you could just get rid of std::function in the constructor and generalize for any functor (which, BTW, is how the Standard library does whenever it needs a functor/callback). For storage you can just use std::function<void()> since it accepts non-void return types too:
class ScopedExit
{
public:
template<typename Functor>
ScopedExit(Functor exitFunction)
{
exitFunc_ = exitFunction;
}
~ScopedExit()
{
exitFunc_();
}
private:
std::function<void()> exitFunc_;
};
int foo() { return 0; }
struct Bar {
void bye(int, int) {}
};
struct Baz {
void operator ()() {}
};
int main() {
const std::string what = "lambda!";
ScopedExit guard1([&]() { std::cout << "yay a " << what << std::endl; });
ScopedExit guard2(foo); // note how std::function<void()> accepts non-void return types
Bar b;
ScopedExit guard3(std::bind(&Bar::bye, &b, 1, 2));
ScopedExit guard4(Baz());
}
Note how your original variadic template class has now become a flexible non-template class with just a templated constructor whose template argument is deduced automatically, and which accepts almost[see note below] any kind of functor you can think about.
Note: I said almost any functor because this doesn't work with default arguments:
void foobar(int = 0) {}
ScopedExit guard5(foobar); // error: too few arguments to function
Even if you stored a Functor directly instead of a std::function<void()> you wouldn't be able to make use of the default arguments anyway (the signature of foobar is still void(int) even with a default argument) so one always has to handle this corner-case at the definition site with something like:
void foobar(int = 0) {}
ScopedExit guard5([]() { foobar(); });
1) You can save arguments in tuple for example. However, in your case, you can simply call exitFunc_() and function definition should be std::function<R()> exitFunction since you already bind arguments to function. Something like this probably
#include <iostream>
#include <functional>
#include <tuple>
template<size_t...>
struct indices {};
template<size_t N, size_t... Is>
struct gen_indices : gen_indices<N - 1, N - 1, Is...>
{
};
template<size_t... Is>
struct gen_indices<0, Is...> : indices<Is...>
{
};
template<class R, class... Args>
class ScopedExit
{
public:
ScopedExit(std::function<R(Args...)> exitFunction, Args&&... args)
: arguments_(std::forward_as_tuple(args...))
{
exitFunc_ = exitFunction;
}
~ScopedExit()
{
call(gen_indices<sizeof...(Args)>());
}
private:
template<size_t... Idx>
void call(indices<Idx...>)
{
exitFunc_(std::forward<Args>(std::get<Idx>(arguments_))...);
}
std::tuple<Args...> arguments_;
std::function<R(Args...)> exitFunc_;
};
template<>
class ScopedExit<void>
{
public:
ScopedExit(std::function<void ()> exitFunction)
{
exitFunc_ = exitFunction;
}
~ScopedExit()
{
exitFunc_();
}
private:
std::function<void ()> exitFunc_;
};
void foo()
{
std::cout << "foo() called\n";
}
class Bar
{
public:
void BarExitFunc(int x, int y)
{
std::cout << "BarExitFunc called with x =" << x << "y = " << y << "\n";
}
};
int main()
{
Bar b;
std::cout << "Register scoped exit func\n";
{
ScopedExit<void, int, int> exitGuardInner
(
std::bind(&Bar::BarExitFunc, &b, std::placeholders::_1,
std::placeholders::_2), 10, 18
);
}
ScopedExit<void> exitGuardOutter(foo);
std::cout << "About to exit from the scope\n";
return 0;
}
2) Should be created like ScopedExit<void>.

How do I avoid implicit conversions on non-constructing functions?

How do I avoid implicit casting on non-constructing functions?
I have a function that takes an integer as a parameter,
but that function will also take characters, bools, and longs.
I believe it does this by implicitly casting them.
How can I avoid this so that the function only accepts parameters of a matching type, and will refuse to compile otherwise?
There is a keyword "explicit" but it does not work on non-constructing functions. :\
what do I do?
The following program compiles, although I'd like it not to:
#include <cstdlib>
//the function signature requires an int
void function(int i);
int main(){
int i{5};
function(i); //<- this is acceptable
char c{'a'};
function(c); //<- I would NOT like this to compile
return EXIT_SUCCESS;
}
void function(int i){return;}
*please be sure to point out any misuse of terminology and assumptions
Define function template which matches all other types:
void function(int); // this will be selected for int only
template <class T>
void function(T) = delete; // C++11
This is because non-template functions with direct matching are always considered first. Then the function template with direct match are considered - so never function<int> will be used. But for anything else, like char, function<char> will be used - and this gives your compilation errrors:
void function(int) {}
template <class T>
void function(T) = delete; // C++11
int main() {
function(1);
function(char(1)); // line 12
}
ERRORS:
prog.cpp: In function 'int main()':
prog.cpp:4:6: error: deleted function 'void function(T) [with T = char]'
prog.cpp:12:20: error: used here
This is C++03 way:
// because this ugly code will give you compilation error for all other types
class DeleteOverload
{
private:
DeleteOverload(void*);
};
template <class T>
void function(T a, DeleteOverload = 0);
void function(int a)
{}
You can't directly, because a char automatically gets promoted to int.
You can resort to a trick though: create a function that takes a char as parameter and don't implement it. It will compile, but you'll get a linker error:
void function(int i)
{
}
void function(char i);
//or, in C++11
void function(char i) = delete;
Calling the function with a char parameter will break the build.
See http://ideone.com/2SRdM
Terminology: non-construcing functions? Do you mean a function that is not a constructor?
8 years later (PRE-C++20, see edit):
The most modern solution, if you don't mind template functions -which you may mind-, is to use a templated function with std::enable_if and std::is_same.
Namely:
// Where we want to only take int
template <class T, std::enable_if_t<std::is_same_v<T,int>,bool> = false>
void func(T x) {
}
EDIT (c++20)
I've recently switched to c++20 and I believe that there is a better way. If your team or you don't use c++20, or are not familiar with the new concepts library, do not use this. This is much nicer and the intended method as outlines in the new c++20 standard, and by the writers of the new feature (read a papers written by Bjarne Stroustrup here.
template <class T>
requires std::same_as(T,int)
void func(T x) {
//...
}
Small Edit (different pattern for concepts)
The following is a much better way, because it explains your reason, to have an explicit int. If you are doing this frequently, and would like a good pattern, I would do the following:
template <class T>
concept explicit_int = std::same_as<T,int>;
template <explicit_int T>
void func(T x) {
}
Small edit 2 (the last I promise)
Also a way to accomplish this possibility:
template <class T>
concept explicit_int = std::same_as<T,int>;
void func(explicit_int auto x) {
}
Here's a general solution that causes an error at compile time if function is called with anything but an int
template <typename T>
struct is_int { static const bool value = false; };
template <>
struct is_int<int> { static const bool value = true; };
template <typename T>
void function(T i) {
static_assert(is_int<T>::value, "argument is not int");
return;
}
int main() {
int i = 5;
char c = 'a';
function(i);
//function(c);
return 0;
}
It works by allowing any type for the argument to function but using is_int as a type-level predicate. The generic implementation of is_int has a false value but the explicit specialization for the int type has value true so that the static assert guarantees that the argument has exactly type int otherwise there is a compile error.
Maybe you can use a struct to make the second function private:
#include <cstdlib>
struct NoCast {
static void function(int i);
private:
static void function(char c);
};
int main(){
int i(5);
NoCast::function(i); //<- this is acceptable
char c('a');
NoCast::function(c); //<- Error
return EXIT_SUCCESS;
}
void NoCast::function(int i){return;}
This won't compile:
prog.cpp: In function ‘int main()’:
prog.cpp:7: error: ‘static void NoCast::function(char)’ is private
prog.cpp:16: error: within this context
For C++14 (and I believe C++11), you can disable copy constructors by overloading rvalue-references as well:
Example:
Say you have a base Binding<C> class, where C is either the base Constraint class, or an inherited class. Say you are storing Binding<C> by value in a vector, and you pass a reference to the binding and you wish to ensure that you do not cause an implicit copy.
You may do so by deleting func(Binding<C>&& x) (per PiotrNycz's example) for rvalue-reference specific cases.
Snippet:
template<typename T>
void overload_info(const T& x) {
cout << "overload: " << "const " << name_trait<T>::name() << "&" << endl;
}
template<typename T>
void overload_info(T&& x) {
cout << "overload: " << name_trait<T>::name() << "&&" << endl;
}
template<typename T>
void disable_implicit_copy(T&& x) = delete;
template<typename T>
void disable_implicit_copy(const T& x) {
cout << "[valid] ";
overload_info<T>(x);
}
...
int main() {
Constraint c;
LinearConstraint lc(1);
Binding<Constraint> bc(&c, {});
Binding<LinearConstraint> blc(&lc, {});
CALL(overload_info<Binding<Constraint>>(bc));
CALL(overload_info<Binding<LinearConstraint>>(blc));
CALL(overload_info<Binding<Constraint>>(blc));
CALL(disable_implicit_copy<Binding<Constraint>>(bc));
// // Causes desired error
// CALL(disable_implicit_copy<Binding<Constraint>>(blc));
}
Output:
>>> overload_info(bc)
overload: T&&
>>> overload_info<Binding<Constraint>>(bc)
overload: const Binding<Constraint>&
>>> overload_info<Binding<LinearConstraint>>(blc)
overload: const Binding<LinearConstraint>&
>>> overload_info<Binding<Constraint>>(blc)
implicit copy: Binding<LinearConstraint> -> Binding<Constraint>
overload: Binding<Constraint>&&
>>> disable_implicit_copy<Binding<Constraint>>(bc)
[valid] overload: const Binding<Constraint>&
Error (with clang-3.9 in bazel, when offending line is uncommented):
cpp_quick/prevent_implicit_conversion.cc:116:8: error: call to deleted function 'disable_implicit_copy'
CALL(disable_implicit_copy<Binding<Constraint>>(blc));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Full Source Code: prevent_implicit_conversion.cc
Well, I was going to answer this with the code below, but even though it works with Visual C++, in the sense of producing the desired compilation error, MinGW g++ 4.7.1 accepts it, and invokes the rvalue reference constructor!
I think it must be a compiler bug, but I could be wrong, so – anyone?
Anyway, here's the code, which may turn out to be a standard-compliant solution (or, it may turn out that that's a thinko on my part!):
#include <iostream>
#include <utility> // std::is_same, std::enable_if
using namespace std;
template< class Type >
struct Boxed
{
Type value;
template< class Arg >
Boxed(
Arg const& v,
typename enable_if< is_same< Type, Arg >::value, Arg >::type* = 0
)
: value( v )
{
wcout << "Generic!" << endl;
}
Boxed( Type&& v ): value( move( v ) )
{
wcout << "Rvalue!" << endl;
}
};
void function( Boxed< int > v ) {}
int main()
{
int i = 5;
function( i ); //<- this is acceptable
char c = 'a';
function( c ); //<- I would NOT like this to compile
}
I first tried PiotrNycz's approach (for C++03, which I'm forced to use for a project), then I tried to find a more general approach and came up with this ForcedType<T> template class.
template <typename T>
struct ForcedType {
ForcedType(T v): m_v(v) {}
operator T&() { return m_v; }
operator const T&() const { return m_v; }
private:
template <typename T2>
ForcedType(T2);
T m_v;
};
template <typename T>
struct ForcedType<const T&> {
ForcedType(const T& v): m_v(v) {}
operator const T&() const { return m_v; }
private:
template <typename T2>
ForcedType(const T2&);
const T& m_v;
};
template <typename T>
struct ForcedType<T&> {
ForcedType(T& v): m_v(v) {}
operator T&() { return m_v; }
operator const T&() const { return m_v; }
private:
template <typename T2>
ForcedType(T2&);
T& m_v;
};
If I'm not mistaken, those three specializations should cover all common use cases. I'm not sure if a specialization for rvalue-reference (on C++11 onwards) is actually needed or the by-value one suffices.
One would use it like this, in case of a function with 3 parameters whose 3rd parameter doesn't allow implicit conversions:
function(ParamType1 param1, ParamType2 param2, ForcedType<ParamType3> param3);