I'd like to create a wrapper for std::unique_ptr<T> and std::make_unique<T> because I think they look ugly and take too long to type. (Yes, I'm that kind of person).
I have completed my UniquePtr type alias with no problem but cannot get my MakeUnique to work. It seems to be a bit of a rabbit hole, and was wondering if anyone here might be able to give me a hand with this?
What I have so far:
template <class T>
using UniquePtr = std::unique_ptr<T>;
template<typename T, typename... Args>
UniquePtr<T> MakeUnique<T>(Args... args) // recursive variadic function
{
return std::make_unique<T>(args);
}
Many thanks in advance!
You need to forward properly the values, and you need to expand the pack.
First, make it compile:
template<typename T, typename... Args>
UniquePtr<T> MakeUnique(Args... args) // not recursive
{ // ^---- no need for <T> when defining function template
return std::make_unique<T>(args...); // the ... expands the pack
}
Then, you need to forward, because args... will copy everything. You want to move rvalues, and copy lvalues:
template<typename T, typename... Args>
UniquePtr<T> MakeUnique(Args&&... args)
{
return std::make_unique<T>(std::forward<Args>(args)...);
}
Related
I'm trying to create a concept that can be used to safe check that a functor has a certain criteria.
This is my code right now:
template<typename T>
void fetch(T&& f)
{
fetch_helper(&f, &std::unwrap_ref_decay_t<T>::operator());
}
template<typename T, typename... Args>
void fetch_helper(T* obj, void (T::*f)(Args...) const)
{
// do stuff
}
I use fetch to take a functor object and then use fetch_helper to operate on it. However I want to implement pref. a concept or type trait that would check that the arguments types are unique (which I already have an implemented concept for IsUnique<T...>). So that the program doesnt compile if the functor doesnt follow the criteria.
// compiles
fetch([](int h){
});
// doesnt compile
fetch([](int h, int j){
});
How can I apply my constrait IsUnique to the args of the functor object in fetch? I tried adding the requires concept to my helper function but that still allows fetch to be called with bad arguments. I somehow has to apply the constraint of the arguments in fetch.
Like this?
template<typename T, typename... Args>
requires IsUnique<Args...>
void fetch_helper(T* obj, void (T::*f)(Args...) const)
{
// do stuff
}
template<typename T>
requires requires (T&& f) {fetch_helper(&f, &std::unwrap_ref_decay_t<T>::operator());}
void fetch(T&& f)
{
fetch_helper(&f, &std::unwrap_ref_decay_t<T>::operator());
}
If I understand you right, you want something like this:
// TypeTraits if IsUnique is a typical trait inheriting from std::true_type or std::false_type
template<typename T, typename... Args>
std::enable_if_t<IsUnique<Args...>::value> fetch_helper(T* obj, void (T::*f)(Args...) const)
{
// do stuff
}
// Concept
template<typename T, typename... Args> requires (IsUnique<Args...>)
void fetch_helper(T* obj, void (T::*f)(Args...) const)
{
// do stuff
}
If you want to check already in fetch you can add a constraint whether fetch_helper is callable with the appropriate arguments (basically repeating the code inside).
Let's say we have a class template like this:
template<typename F>
class A
{
public:
template<typename... Args>
A(F f, Args... args)
{ /* Do something... */ }
};
And now I want to use it in some way like this one:
A<int(int)> a(::close, 1);
Now the question: is there any way to omit the <int(int)> because a compiler can know this information for the ::close? There is no need to save the "design" of the template.
As for concrete task, I need to design a template of a class. Objects of this class could take a function and parameters for this function at construction time and call this function later.
No, you (currently) cannot. The standard way of doing this is by creating "make_like" function (such as make_pair, make_optional ...):
template<typename F, typename... Args>
A<std::decay_t<F>> make_A (F &&f, Args&&... args) {
return {std::forward<F>(f), std::forward<Args>(args)...};
}
C++17 will introduce template argument deduction for class which will allow you to do exactly what you want (see also Barry's answer below).
Thanks to the adoption of template parameter deduction for constructors, in C++17, you'll be able to just write:
A a(::close, 1);
Before that, you'll just need to write a factory to do the deduction for you:
template <class F, class... Args>
A<std::decay_t<F>> make_a(F&& f, Args&&... args) {
return {std::forward<F>(f), std::forward<Args>(args)...};
}
auto a = make_a(::close, 1);
This is a little verbose, but at least you don't need to worry about efficiency - there will be no copies made here thanks to RVO.
You cannot omit the arguments of a template class, unless they are defaulted. What you can do is have a maker function which deduces the argument and forwards this argument to the template class, returning an object of the appropriate instantiation.
template<typename F, typename... Args>
A<F> make_A(F f, Args&&... args) {
return A<F>(f, std::forward<Args>(args)...);
}
Why does the following compile under C++11? (I know it won't link.) I would expect the std::enable_if test to fail since 1() is not a function type.
#include <type_traits>
template <typename Func, typename... Args>
typename std::enable_if<std::is_function<Func(Args...)>::value>::type
delegate(Func, Args...);
int main(void) {
delegate(1); // << Why does this line compile?
return 0;
}
Func is int, Args is empty, so Func(Args...) is int(), i.e., "function of () returning int".
Anything that is_function returns true for can't be the type of a by-value function parameter, so it's not obvious what you want to do.
I was trying to get delegate to only be callable when Func is a
function (preferably function pointer) that can be applied to Args...
Use expression SFINAE for that.
template <typename Func, typename... Args>
auto delegate(Func f, Args... args) -> decltype(f(args...), void());
Depending on what you actually want to do, you may want to std::move f and args.
The code you have written will always yield true. You probably meant std::is_function<Func>...
Though not sure, it seems like you do not need enable_if at all, and you'd better of with a simple
template <class R, class... ARGS>
R delegate2(R (*fun)(ARGS...), ARGS...);
However, if I am wrong and enable_if is a key to success in your case, here is how you can do this:
#include <type_traits>
template <typename Func, typename... Args>
typename std::enable_if<std::is_function<std::remove_pointer_t<Func>>::value>::type
delegate(Func, Args...);
void check(int);
int main(void) {
delegate(check, 10); // << good line compiles
delegate(10); // << this bad line does not
return 0;
}
Based on this comment:
I was trying to get delegate to only be callable when Func is a function (preferably function pointer) that can be applied to Args...
you're using the wrong type trait. To check if Func is callable with Args..., you need to construct an expression that would actually call an instance of Func with those arguments. For that, there's std::result_of_t (in C++14, it becomes SFINAE friendly):
template <typename Func, typename... Args,
class R = std::result_of_t<Func(Args...)>>
R delegate(Func, Args...);
Or, in C++11, just write that out with decltype and declval:
template <typename Func, typename... Args,
class R = std::declval<Func>()(std::declval<Args>()...)>
R delegate(Func, Args...);
First, I'm sorry if I make big english mistakes, I'm french but I'm trying to write as best as I can! Well, I'm struggling with C++11 variadic template. I want to do something a little tricky.
Indeed, I want to specialize the return type of my template, knowing that it is a variadic template.
My goal is to achieve something like:
l.callFun<int>("addition", 40, 1, 1);
The specialization corresponds to the return type that the user want. It is a Lua binding, so I can't determine the return type if the user doesn't precise it (obviously, the default, if no specialization, would be void return). Later, is the name of the function that is called in Lua. Then, the 3 integers corresponds to my variadic template.
Right now, my template is looking like this :
template <typename Z, typename T, typename... U>
Z LuaScript::callFun(const std::string& name, const T& head, const U&... tail);
But it appears that I cannot make a partial specialization of a template function. Is there anybody that could help me ?
Thank you very much!
Help and documentation very much appreciated pheedbaq, but finally, I came with a really simple solution. I didn't tought of it that way, so I'll experiment with this way of operator overloading thanks to you ;)
What I've done is packing the variadic arguments, and calling another template to specialize on the return type. So I have something like that:
template <typename Z, typename... T>
Z LuaScript::callFun(const std::string& name, const T&... args)
{
Z ret;
callFunReal(args);
[...]
ret = returnType<Z>();
return (ret);
}
It was really quite simple, but couldn't see exactly how to do it... Thanks to everyone! :)
A solution that does not require changing your interface is to forward the function call to a template<> class, where you can specialize to your hearts content:
template<typename R, typename... Ts>
struct DoCallFun {
R operator()( LuaScript* self, std::string const& name, Ts&&... ts ) {
}
};
template <typename Z, typename... T>
Z LuaScript::callFun(const std::string& name, Ts&&... ts) {
return DoCallFun<Z, Ts...>()( this, name, head, std::forward<Ts>(ts)... )
}
and we implement the body of callFun within DoCallFun. If it needs access to private variables in LuaScript we make DoCallFun a friend.
Now, a better solution might be to use a "traits class" for much of the return-type dependent behavior. If you need to call a different function based on the return type, instead of writing the same callFun once for each return type with a slight difference, you can create a "traits class" where you isolate the difference based on return type.
Suppose you need to call int CallAndReturnInt(...) if the type is int and double CallAndReturnDouble(...) if the type is double. Instead of having two bodies of callFun, write a traits class:
template<typename T>
struct lua_return_traits;
template<>
struct lua_return_traits<int> {
template<typename... Ts>
static int call_and_return( Ts&&... ts ) {
return CallAndReturnInt( std::forward<Ts>(ts) );
}
};
template<>
struct lua_return_traits<double> {
template<typename... Ts>
static double call_and_return( Ts&&... ts ) {
return CallAndReturnDouble( std::forward<Ts>(ts) );
}
};
and similar techniques for other ways your method should differ based on the return type.
Perfect forwarding the initial call to a helper class member function should facilitate what you want.
template<typename Z>
struct callFun_helper {
template<typename T, typename... U>
static Z help(const std::string& name, const T& head, const U&... tail) {
Z thing;
//do something with "thing"
return thing;
}
};
template<typename Z, typename S, typename T, typename... U>
auto callFun(S&& s, T&& t, U&&... u)
-> decltype(callFun_helper<Z>::help(std::forward<S>(s), std::forward<T>(t), std::forward<U>(u)...)) {
return callFun_helper<Z>::help(std::forward<S>(s), std::forward<T>(t), std::forward<U>(u)...);
}
//main
callFun<string>("addition", 40, 1, 1)
The link below might help you with partial template specialization if you want to know more about what you can/can't do with it. Also, don't forget to mark an answer if you want to continue getting answers in the future here at StackOverflow :)
Why Not Specialize Function Templates?
I have a pretty exotic problem, since I am trying to create some sort of a compiler...
I want to pass a lambda expression to a templated function like this:
template<class T>
delegate<T>* bind(std::function<T> func)
{
return nullptr;
}
So that I can now call
bind([&](int a) { // do something });
... So normally, this wouldn't be a problem, since std::function is able to capture a lambda. But here the problem is that (let's assume) I don't know or don't want to provide the info about what "T" is exactly. It could be any function signature you could also insert into std::function<>...
I also need to pass this "inferred" signature back to the "delegate" class I want to return and that delegate class needs to be a pointer to class...
For now I have come up with this:
template<class T>
struct delegate : public std::function<T>
{
delegate(const std::function<T>& func) : std::function<T>(func) { }
delegate(const delegate<T>& func) { }
};
template<class T>
delegate<T>* bind(std::function<T>&& func)
{
return new delegate<T>(std::forward<std::function<T>>(func));
}
But the above example of a call to "bind" fails with "failed template argument deduction". How can I get this to work without having to specify the "T" parameter explicitly when calling "bind" (then it works, at least)?
Since in theory my compiler has all the info to workaround this issue, I could just insert the instance of "T", but this would make the generated code unnecessarily convoluted.
BTW, I am using the lastest Clang compiler.
Here is the final solution:
template<typename T> struct get_signature;
template<typename Mem, typename Ret, typename... Args> struct get_signature<Ret(Mem::*)(Args...) const> {
typedef Ret type(Args...);
};
template<class T>
delegate<typename get_signature<decltype(&T::operator())>::type>* bind(T func)
{
return nullptr;
}
Be aware that you may need to adjust the "const" modifiers to your needs.
First, you have completely screwed up your rvalue references. Your forwarding does not work at all.
Secondly, that's impossible in some cases.. For some function objects, you could infer the signature by taking the member function pointer to operator() and inspecting it's signature. But for others, they will be overloaded and it will not work.
template<typename T> struct get_signature;
template<typename Mem, typename Ret, typename... Args>
struct get_signature<Ret(Mem::*)(Args...)> {
typedef Ret(Args...) type;
};
template<class T>
delegate<typename get_signature<&T::operator()>::type>* bind(T func)
{
return nullptr;
}
Thirdly, std::bind?