I am trying to write my own inplace_function and came across a strange problem where the templated constructor was being called and not the assignment operator on assignment. I am not sure if it is related to overload resolution or something else. Here is the code that will help you understand even more:
template <size_t, typename>
class inplace_function;
template <size_t N, typename R, typename... Args>
requires std::is_invocable_r_v<R, R (*)(Args...), Args...>
class inplace_function<N, R(Args...)>
{
public:
using result_type = R;
inplace_function() = default;
template <typename Func>
inplace_function(Func&& func) noexcept
{
// initialization
}
~inplace_function() noexcept
{
// destruction code
}
template <typename Func>
requires std::invocable<Func>
inplace_function& operator=(Func&& other) noexcept
{
// assignment logic
return *this;
}
private:
// data
};
Test code:
int multiply(int x, int y)
{
return x * y;
}
struct Add
{
int operator()(int x, int y) const
{
return x + y;
}
};
struct Foo
{
int add(int x, int y) const
{
return x + y;
}
};
inplace_function<8, int(const Foo&, int, int)> func(&Foo::add);
inplace_function<8, int(int, int)> func1(multiply);
inplace_function<8, int(int, int)> func2([](int x, int y) { return x + y; });
inplace_function<8, int(const Foo&, int, int)> func3;
func3 = func;
inplace_function<8, int(int, int)> func4;
const Foo foo;
CHECK(func1(3, 3) == func(foo, 3, 6));
CHECK(func2(0, 9) == 9);
CHECK(func3(foo, 0, 9) == 9);
func4 = [](int a, int b) { return a + b; };
CHECK(func4(6, 3) == 9);
func4 = multiply;
CHECK(func4(3, 6) == 18);
func4 = Add{};
CHECK(func4(8, 1) == 9);
func2 = multiply;
CHECK(func2(0, 9) == 0);
Not a single time the assignment operator was called. I am aware of copy-elision but I don t it plays a role in my scenario.