class Base
{
public:
Base(Base&&) = default;
};
class Derived: public Base
{
public:
Derived(Derived&&) = default;
};
int main()
{
static_assert(std::is_nothrow_move_constructible_v<Derived>, "Error noexcept");
}
In this code even if neither Derived nor Base declared move constructor noexcept but still this passes static assert on std::is_nothrow_move_constructible_v<Derived>.
Why?
Related
Here is an example code:
class Interface
{
public:
virtual ~Interface(){}
virtual void Start() = 0;
};
class MockInterface: public Interface
{
public:
MOCK_METHOD0(Start, void());
};
class T
{
public:
T(std::unique_ptr<Interface>& impl): impl_(impl){}
private:
std::unique_ptr<Interface>& impl_;
};
I would like to create a strict mock but I'm not sure how to construct it as unique ptr and then pass to T constructor.
#include <gmock/gmock.h>
#include <gtest/gtest.h>
class Interface
{
public:
virtual ~Interface(){};
virtual void Start() = 0;
};
class MockInterface : public Interface
{
public:
MOCK_METHOD0( Start, void() );
};
class T
{
public:
explicit T( std::unique_ptr< Interface > impl ) :
impl_( std::move( impl ) ) {}
void Start()
{
impl_->Start();
}
private:
std::unique_ptr< Interface > impl_;
};
TEST( Interface_test, Interface )
{
auto mock{ std::make_unique< MockInterface >() };
EXPECT_CALL( *mock, Start() );
auto t{ T{ std::move( mock ) } };
t.Start();
}
Posting a complete answer with an example of usage and an update to the class T. It is recommended to move the unique_ptr instead of taking a reference.
class factory final {
private:
class object final {
public:
int x;
};
public:
inline static std::shared_ptr<object> createObject() { return std::make_shared<object>(); }
};
int main() {
auto item1 = factory::createObject();
std::shared_ptr<factory::object> item2 = factory::createObject();
return std::getchar();
}
Hello. The code above fails to compile with VS2015 because I cannot access private member (class object) of class factory. So far so good and it makes alot of sense. I am curious why does the auto line works. It does resolve to correct type and works as intended.
Example
In example above I've tried to store pointer-to-member_function of the overloaded function in the template-based class.
The problem is that overloaded function uses Base class as parameter and current class is template class from Derived class.
Handlers
#include <iostream>
#include <string>
class HandlerA
{
public:
void foo(const std::string& m)
{
std::cout << "HandlerA: " << m << '\n';
}
};
class IBaseHandlerB
{
public:
virtual void bar(const std::string& m) = 0;
};
class HandlerB : public IBaseHandlerB
{
public:
virtual void bar(const std::string& m) override
{
std::cout << "HandlerB: " << m << '\n';
}
};
Events
class Event
{
public:
virtual void write(HandlerA&) const = 0;
virtual void write(IBaseHandlerB&) const = 0;
};
class FancyEvent : public Event
{
public:
virtual void write(HandlerA& h) const override
{
h.foo("FancyEvent");
}
virtual void write(IBaseHandlerB& h) const override
{
h.bar("FancyEvent");
}
};
Wrapper and usage example
template <typename T, typename Event>
class HandlerWrapper
{
public:
HandlerWrapper(T&& handler, void(Event::*func)(T&) const)
: m_handlerImpl(std::forward<T>(handler))
, m_eventFn(func) {}
void call(const Event& event)
{
(event.*m_eventFn)(m_handlerImpl);
}
private:
T m_handlerImpl;
void(Event::*m_eventFn)(T&) const;
};
// ------- Usage -------
int main(void)
{
FancyEvent event;
// OK
HandlerWrapper<HandlerA, Event> h(HandlerA(), &Event::write);
h.call(event);
// Error: Candidate constructor not viable: no overload of
// 'writeWithHandler' matching
// 'void (LogEvent::*)(CEFEventHandler &) const' for 2nd argument
HandlerWrapper<HandlerB, Event> h2(HandlerB(), &Event::write);
h2.call(event);
return 0;
}
Question
How to specify correct template type to accept function-to-Base if class template argument is derived from that Base?
My goal is to pass just pointer-to-member_function to another class whenever that class is the same with type that function accepts or derived from it.
Here I have some interesting code. Does anyone know how to get subtype from myClass without auxiliary parameter in template?
Note: Maybe myClass template too.
class myClass
{
public:
struct tPacaje
{
int data;
};
};
template <class T>
class executorClass
{
public:
void todo(T::tPacaje ob)
{
...
}
};
You are trying to use a type so need to tell the compiler you are using a typename:
template <class T>
class executorClass
{
public:
void todo(typename T::tPacaje ob)
{
//^-------
//...
}
};
I have an interface, and I was trying an example on dynamic polymorphism as follows:
#include <iostream>
using namespace std;
class foo{
public:
virtual void set();
virtual void printValue();
};
class fooInt : public foo{
private:
int i;
public:
int get(){
return i;
}
void set(int val){ //override the set
i = val;
}
void printValue(){
cout << i << endl;
}
};
int main(){
foo *dt; //Create a base class pointer
dt = new fooInt; //Assign a sub class reference
dt->set(9);
}
However when I compile this, I get no matching function for call to ‘foo::set(int)’. Where am I going wrong? I tried to read this article, and I still couldn't figure out the mistake.
class foo has no method set(int). It has a method set(), but no method set(int).
If you intend to override an inherited method, the superclass method and your method must have the same signature:
class foo {
...
// If you really want an abstract class, the `= 0`
// ensures no instances can be created (makes it "pure virtual")
virtual void set(int) = 0;
...
}
This is because your definition of
virtual void set();
Should be
virtual void set(int val);
The corrected program is given here
#include <iostream>
using namespace std;
class foo {
public:
virtual void set(int val)=0;////////here you have void set() function with no argument but you tried to override void set(int val) which take one argument.
virtual void printValue()=0;
};
class fooInt : public foo{
private:
int i;
public:
fooInt()
{
cout<<"constructor called\n";
}
int get(){
return i;
}
void set(int val){ //override the set
i = val;
}
void printValue(){
cout << i << endl;
}
};
int main(){
foo *dt; //Create a base class pointer
dt=new fooInt;
dt->set(9);
dt->printValue();
}
Fault of the previous program were
1.You tried to override set() {no argument} with set(int val){one argument}.
2.When a class contain a pure virtual function,it must be implemented by its derived classes.
3. No object can be created of a class which contain a pure virtual function.But ref can be created.
Thanks