Reputation: 145
How can I overload the cb
function template so that the code will compile? Now the exception is:
error C2535: void notify_property <T> :: cb (const F &): member function already defined or declared
But the templates are different.
template <typename T>
class notify_property {
public:
virtual ~notify_property() {}
//1
template <typename F, typename = std::enable_if_t<std::is_void_v<std::invoke_result_t<std::decay_t<F>>>>>
void cb(const F& task)
{
set_cb([task]
{
try { task(); }
catch (...) {}
});
}
//2
template <typename F, typename = std::enable_if_t<std::is_void_v<std::invoke_result_t<std::decay_t<F>, std::decay_t<T>>>>>
void cb(const F& task)
{
set_cb([this, task]
{
try { task(_value); }
catch (...) {}
});
}
//3
template <typename F, typename... A, typename = std::enable_if_t<std::is_void_v<std::invoke_result_t<std::decay_t<F>, std::decay_t<T>, std::decay_t<A>...>>>>
void cb(const F& task, const A &...args)
{
set_cb([this, task, args...]
{
try { task(_value, args...); }
catch (...) {}
});
}
virtual T& operator= (const T& f)
{
if (f != _value)
{
_value = f;
if (_cb != nullptr) _cb();
}
return _value;
}
virtual const T& operator() () const { return _value; }
virtual explicit operator const T& () const { return _value; }
virtual T* operator->() { return &_value; }
protected:
template <typename F>
void set_cb(const F& cb) { _cb = std::function<void()>(cb); }
std::function<void()> _cb = nullptr;
T _value;
};
Аnswer:
//1
template <typename F, std::enable_if_t<std::is_void_v<std::invoke_result_t<std::decay_t<F>>>>* = nullptr>
void cb(const F& task)
{...}
//2
template <typename F, std::enable_if_t<std::is_void_v<std::invoke_result_t<std::decay_t<F>, std::decay_t<T>>>>* = nullptr>
void cb(const F& task)
{...}
Upvotes: 3
Views: 109
Reputation: 11
In my opinion this is happening due to same parameters in function 1 and function 2.
The solution for this is pretty simple. Changing the parameters in one of the 2 functions works just fine. Just add a parameter on function 2 (or 1) of the type int. While calling it just pass 0 as an argument. If it doesn't work then do comment down below :)
(I don't have so much reputation yet so I can't comment. So I answered instead :) )
Upvotes: 0
Reputation: 63947
typename = std::enable_if_t
is problematic if duplicated because - as your error mentions - you're defining the same function multiple times, merely with a different default parameter.
Change every type template parameter
// Type parameter, with a defaulted type
typename = std::enable_if_t< ... >
// ^^^^^^^^^^^ remove!
to a non-type template parameter that is part of the function's signature:
// Value (pointer) parameter, with a defaulted value
std::enable_if_t< ... >* = nullptr
// ^^^^^^^^^^^ add
(Or, as cppreference does it)
// Value (bool) parameter, with a defaulted value
std::enable_if_t< ..., bool> = true
// ^^^^^^^^^^^^^^ add
Upvotes: 4