For example, I want to get a list of maximum values from two sequences, left and right, and save the results in max_seq, which are all previously defined and allocated,
std::transform(left.begin(), left.end(), right.begin(), max_seq.begin(), &max<int>);
But this won't compile because the compiler says
note: template argument deduction/substitution failed
I know I can wrapper "std::max" inside a struct or inside a lambda. But is there a way directly use std::max without wrappers?
std::max has multiple overloads, so the compiler is unable to determine which one you want to call. Use static_cast to disambiguate and your code will compile.
static_cast<int const&(*)(int const&, int const&)>(std::max)
You should just use a lambda instead
[](int a, int b){ return std::max(a, b); }
Live demo
Template expansion and instanciation occur at compile time. So you can pass a template function only to templates.
You could pass an instanciated (templated) function at run-time (then it is an "ordinary" C++ function).
Related
I was wondering if writing anything resembling this declaration (making use of the parameter pack) is possible.
decltype(auto) (*funcPtr)(...);
If possible, I would also like to know about alternative ways to declare such a pointer.
C++ is a statically typed language. All function argument types and return types must be known at compile time. You cannot declare a function that returns arbitrary types (well, I guess you could return std::any, but I can't think of a case where you'd want to).
You can use templates, however, to create function templates where the compiler will stamp out multiple versions of a function for you, so you don't have to write them all yourself.
Remember that auto and decltype(auto) is not magic. They are just syntactic sugar for what you'd otherwise write yourself if they didn't exist. They do not enable any new features that weren't already in the language. They just make such features easier to use.
No, there is no type such as pointer to function "that returns anything". There are only pointers to a function that returns some type or void. auto merely deduces the type from an initialiser, and there is nothing to deduce the type from in your example.
You can however have a function template where the instance of the template is a function that returns a type specified by a template argument:
// function template
template<class T>
T foo() {
return {};
}
Likewise, you can have a variable template that is a pointer to function whose return type is specified by a template variable:
// variable template
template<class T>
T (*funcPtr)() = foo;
// example usage
int main() {
return funcPtr<int>();
}
My problem is std::tuple has no member function like
auto t = std::make_tuple(1,2,"foo");
t.get(1);
how can I implement such a function when I create a wrapper class arround std::tuple
Such a function cannot exist (in current C++ standards) because function arguments are a run-time mechanism, but return types need to be known at compile time. So the latter cannot depend on the former.
Use std::get instead:
auto v = std::get<1>(someTuple);
To get a value from a tuple you should use std::get<0>(tuple)
You can't have a get function like you want, because tuple elements are not necessarily of the same type (in your example you have ints and a string). What would the return type of this get function be?
You can add a template get function, so that derived_tuple.get<0>() will return the first element.
There are actually two questions here. The first is
why get has a template integral argument rather than a accepting this
value as a function argument.
This has been answered.
The other question is
why get is a free function rather than a member function
To this the answer seem to be - so that called on templated types, it would not require usage of keyword typename. Example. Suppose, tuple would have a get as a member, it would have to be called like that in below code:
template <class T> void foo(T tuple) {
tuple.template get<1>() = 42;
}
This template is certainly a nuisance.
I am newbie to c++ template. If I defined a template method, which I found I can call non template method
for example
void non_template(double x)
{
}
template<typename T>
void testClass<T>::method1() {
/*****/
T var1;
//call a nontemplate here using var1
non_template(var1);
}
I am not sure why this can be allowed without any compilation errors; If my var1 is int, will it be wrong?
I am not sure why this can be allowed without any compilation errors; If my var1 is int, will it be wrong?
Template classes and functions work slightly differently from non-templated ones: checking for validity is done in 2 passes - once at definition time, the other at instantiation (when the method is first called) time.
When processing the template function, it checks things like syntax, and type not dependent on the template arguments. If these succeed, it will not complain and store the definition of the template in it's state.
When you try to call (instantiate) the template with a particular set of arguments, it will go back to the definition stored and recheck thing that are dependent on the type of parameters passed in.
So, if I try to call your function with an int, double and a float like:
test_calls.method(5.0); // Works as expected
test_calls.method(5); // Works, because int can be converted to double implicitly.
test_calls.method("Hello"); // Doesn't work, because "non-templated" cannot be call with a char const* argument.
The compiler looks for matches by applying permitted conversions to parameters in order to find a match (i.e. a function that can be called). That is true for all functions, not just templates.
If T is a type that can be implicitly converted to a double, then it will be so the "non template" function can be called.
If T cannot be implicitly converted to double, then the compiler will report it cannot find a match in some way.
How can I in C++ make a function accept every Object, so I can give it numbers, String or other Objects. I am not very well in C++, I hope it's not a totally stupid question...
Edit: Ok, an example: if you want to try to wrap the std::cout streams into normal functions, that funtion should be able to accept everything - from Integers over Floats to complex Objects. I hope it's more clear now!
You can overload your function for different types, i.e.
size_t func(int);
size_t func(std::string);
Alternatively and/or additionally, you can provide a function template, which is a way to tell the compiler how to generate your function for any particular type, for example
template<typename T>
size_t func(T const&) { return sizeof(T); }
You may use more advanced techniques such as SFINAE to effectively overload those template functions, i.e. to use different templates for different kind of types T (i.e. integral types, pointer, built-in types, pod, etc). The compiler will then pick the best-fitting func() (if any) for any function call it encounters and, if this is a template, generate an appropriate function.
This requires no re-coding.
A completely different approach is to use a generic erasure type, such as boost::any, when the function will need to resolve the expected types at coding-time (as opposed to compile-time):
size_t func(boost::any const&x)
{
auto i = boost::any_cast<const int*>(x);
if(i) return func(*i);
// etc for other types, but this must be done at coding time!
}
You can use templates for this purpose:
template <typename T>
void foo(T const & value)
{
// value is of some type T, which can be any type at all.
}
What you can actually do with the value may be rather limited without knowing its type -- it depends on the goal of your function. (If someone attempts to call the function with an argument type that causes that function specialization to be ill-formed then your template function will fail to instantiate and it will be a compile-time error.)
I'm not sure what you're trying to accomplish, but you can pass a void pointer as a parameter.
void foo(void* bar);
If I understood you correctly you might wanna try using templates http://en.cppreference.com/w/cpp/language/function_template
You are probably looking for templates.
I suggest you read this.
The std::get function uses template parameter as a regular parameter.
As an example:
std::tuple <int, double, long &, const char *> bar(18, 6.5, 12, "Hello!");
cout << std::get<2>(bar); // Print the tuple’s third element.
Why this function designed this way?
Why not using a regular parameter instead?
For example, something like: std::get(bar, 2) or std::get(2, bar)
A function must have a well-defined return type, specified at compile time. Here the template specialisation get<2> is a function returning long&; but your version would have to return a different type depending on its argument, specified at runtime, which is impossible.
Hopefully, this demonstration is explanation enough:
int x;
std::cin >> x;
auto i = std::get(bar, x);
Keeping in mind that in C++ the type of any object must be known at compile time, what type is i? Note that you cannot pass variables as template arguments, you must pass constant expressions, so the above problem doesn't exist when the integer is a template argument.
Perhaps more relevant to your example is this.
std::cout << std::get(bar, x);
Each overload of operator<< is a different function. Which function to call is determined at compile time, based on the arguments. So how can the compiler determine which overload to call in the above statement? What if you had a tuple member which didn't even have an overload?