Consider the following classes,
template <class L>
class A {
public:
A(L l) : _l(l) {}
private:
L _l;
};
class B {
public:
B(int x) : _x(x), _a([this]() { return _x; }) {}
private:
int _x;
A<???> _a;
};
I am not sure how to specify the type at ???. std:: function<int()> works, but to my knowledge, this implies virtual function calls (of course, this does not have to be bad, but it would be interesting how to do this properly).
Rather than a lambda, you can use a function object that's roughly equivalent.
template <class L>
class A {
public:
A(L l) : _l(l) {}
private:
L _l;
};
class B {
struct GetX
{
int operator()() const { return _b->_x; }
B * _b;
};
public:
B(int x) : _x(x), _a(GetX{ this }) {}
private:
int _x;
A<GetX> _a;
};
Related
I need a static analyzer that will find uninitialized variables members/variables... of a templated class type.
Can any analyzer do this? I tried clang/cppcheck and a couple of others with no luck.
Here is my test code:
enum class ViewMode
{
One = 1,
Two = 2,
Three = 3,
Four = 4
};
class TestClass {
public:
TestClass() {}
};
template<typename T, bool C = std::is_copy_constructible<T>::value>
class TemplateTest
{
public:
TemplateTest() {}
TemplateTest(const T& value)
: value_(value)
{}
TemplateTest(const TemplateTest&) = delete;
TemplateTest(TemplateTest<T, C>&& rhs)
: value_(std::move(rhs.value_))
{}
TemplateTest(T&& value)
: value_(std::move(value))
{}
private:
T value_;
};
class StaticAnalysisTest {
public:
StaticAnalysisTest() {}
void DoSomething() {
}
private:
ViewMode viewMode_; //this uninitialized warning is found
TemplateTest<ViewMode> viewMode2_; //this one is not
};
I have further distilled the problem to:
class Foo
{
private:
int m_nValue;
public:
Foo() {};
Foo(int value) : m_nValue(value) {}
int GetValue() { return m_nValue; }
};
class Bar
{
public:
Bar(){}
void DoSomething() {
Foo foo;
}
};
This does not generate an unitialized variable warning, but when I comment out:
//Foo(int value) : m_nValue(value) {}
it does
Thank you for evaluating Cppcheck. A warning is given for the second example, in case you add the --inconclusive flag, for example:
class Foo
{
private:
int m_nValue;
public:
Foo() {};
explicit Foo(int value) : m_nValue(value) {}
int GetValue() const
{
return m_nValue;
}
};
class Bar
{
public:
Bar() {}
static void DoSomething() {
Foo foo;
}
};
The output from Cppcheck
$ cppcheck --enable=all --inconclusive uninitmembervar.cpp
[uninitmembervar.cpp:6]: (warning, inconclusive) Member variable 'Foo::m_nValue' is not initialized in the constructor.
I am doing C++ from 2 years or so , I say why we need constructors in class and not in structures , and why we cant do constructor overloading in structure...
why we need constructors in class
We don't.
// Perfectly valid
class Foo
{
public:
int x
};
why we cant do constructor overloading in structure...
We can.
// Look, ma!
struct Bar
{
Bar operator+(const Bar& other);
};
I don't know where you heard these claims but it certainly wasn't from trying it out.
A user-defined type declared with the keyword struct is a class.
The only difference between struct and class in C++ is visibility; a struct defaults to public while a class defaults to private.
Once you get past that initial visibility, however, they are indistinguishable. A struct is a class with default public visibility.
These two pieces of code have exactly the same effect.
struct MyClass {
MyClass(int i) : m_i(i) {}
int getI() const { return m_i; }
void setI(int i) { m_i = i; }
private:
int m_i;
};
// is exactly the same as
class MyClass {
public:
MyClass(int i) : m_i(i) {}
int getI() const { return m_i; }
void setI(int i) { m_i = i; }
private:
int m_i;
};
or put another way
class MyClass {
int m_i;
public:
MyClass(int i) : m_i(i) {}
int getI() const { return m_i; }
};
struct MyClass {
private:
int m_i;
public:
MyClass(int i) : m_i(i) {}
int getI() const { return m_i; }
};
I have two classes with same interface methods:
struct ImplGenerated {
int foo(int x, int y);
void bar(double x);
....
};
struct ImplCustom {
int foo(int x, int y);
void bar(double x);
.....
};
And class Wrapper:
struct Wrapper {
Wrapper(ImplGenerated * i): m_generated(i), m_custom(0) {}
Wrapper(ImplCustom * i): m_generated(0), m_custom(i) {}
int foo(int x, int y);
void bar(double x);
....
private:
??? getImpl();
ImplGenerated * m_generated;
ImplCustom * m_custom;
};
int Wrapper::foo(int x, int y) {
return getImpl()->foo(x, y);
}
void Wrapper::bar(double x) {
getImpl()->bar(x);
}
Is it possible to write some C++ construction (class or any other, but not macros) instead getImpl() for resolving current implementation object and call corresponding method?
like this:
???? getImpl() {
return m_custom ? m_custom : m_generated;
}
Note:
Only changes to ImplCustom could be applied (add base class or make template or something else), ImplGenerated is auto-generated by external project therefore couldn't be changed (add base class is impossible).
Wrapper could not be template, because is interface class.
Update:
It is impossible to derive ImplCustom from ImplGenerated.
The solution I see here is to create a wrapper
The goal of this solution is to generate an interface for your two unrelated classes.
Let's start by making a Base classe:
struct ImplInterface {
virtual int foo(int x, int y) = 0;
virtual void bar(double x) = 0;
// ...
};
Now you can create wrapper for each Impl you got:
struct GeneratedWrapper : ImplInterface {
virtual int foo(int x, int y) {
_impl.foo(x, y);
}
virtual void bar(double x) {
_impl.bar(x);
}
private:
ImplGenerated _impl;
};
struct CustomWrapper : ImplInterface {
virtual int foo(int x, int y) {
_impl.foo(x, y);
}
virtual void bar(double x) {
_impl.bar(x);
}
private:
ImplCustom _impl;
};
Now you can use these wrapper like this:
ImplInterface* wrapper = new GeneratedWrapper(implGenerated);
This method could be much shorter using templates, let's make One wrapper for your new interface:
template<typename T>
struct EveryImplWrapper : ImplInterface {
virtual int foo(int x, int y) {
_impl.foo(x, y);
}
virtual void bar(double x) {
_impl.bar(x);
}
private:
T _impl;
};
Now you can use it like this:
ImplInterface* = new EveryImplWrapper<ImplCustom>(implCustom);
If you can't modify the existing classes, you can still add a facade to provide post-hoc polymorphism. That is:
Wrapper could not be template, because is interface class
is only partly true. You can have a non-templated interface (ABC) and a templated concrete subclass.
// publically visible parts
struct ImplInterface {
virtual ~ImplInterface() {}
virtual int foo(int x, int y) = 0;
virtual void bar(double x) = 0;
....
};
struct Wrapper {
// ...
ImplInterface *Wrapper::getImpl();
// ... do you want to keep the same impl selection across calls?
ImplInterface *m_impl;
};
// implementation details can be hidden in a cpp file
template <typename RealImpl>
struct ImplFacade: ImplInterface {
RealImpl pimpl_;
explicit ImplFacade(RealImpl *impl) : pimpl_(impl) {}
int foo(int x, int y) override { return pimpl_->foo(x,y); }
void bar(double x) override { pimpl_->bar(x); }
};
ImplInterface *Wrapper::getImpl() {
if (!m_impl) {
if (m_custom)
m_impl = new ImplFacade<ImplCustom>(m_custom);
else
m_impl = new ImplFacade<ImplGenerated>(m_generated);
}
return m_impl;
}
Ideally you should be using unique_ptr for the new member in real code.
If you can use the c++11 Standard you can use std::function to accomplish this:
struct Wrapper {
Wrapper(ImplGenerated * i):
foo(std::bind(&ImplGenerated::foo, i)),
bar(std::bind(&ImplGenerated::bar, i)) {}
Wrapper(ImplCustom * i):
foo(std::bind(&ImplCustom ::foo, i)),
bar(std::bind(&ImplCustom ::bar, i)) {}
//Now the functions are member variables but it works the same way
std::function<int(int x, int y)> foo;
std::function<void(double x)> bar;
....
//If you don't Need to destruct the impl-objects then you don't even Need to store them
};
I believe what you're wanting is to use inheritance / interface:
struct ImplInterface {
virtual int foo(int x, int y) = 0;
virtual void bar(double x) = 0;
....
};
struct ImplGenerated : public ImplInterface {
virtual int foo(int x, int y);
virtual void bar(double x);
....
};
struct ImplCustom : public ImplInterface {
virtual int foo(int x, int y);
virtual void bar(double x);
.....
};
now your getImpl() will return a ImplInterface*
Or if you can't add a base class, then in your Wrapper class instead of getImpl() do this:
int foo(int x, int y)
{
if (m_generated != nullptr)
{
return m_generated->foo(x,y);
}
else if (m_custom != nullptr)
{
return m_custom->foo(x, y);
}
throw "hey dude!";
}
I know it's a lot of work, but hey you've no base class to work with.
Let's say I have two classes, A and B:
class B;
class A
{
private:
int an_int;
B *something_else;
public:
A(int n) : an_int(n), something_else(nullptr) {}
};
class B
{
private:
int an_int;
A *something_else;
public:
B(int n) : an_int(n), something_else(nullptr) {}
};
How can I make it so that I don't have to prototype B in order to have a pointer to a B object in class A?
This solution is most probably what is intended in an exercise about inheritance where you can't use a forward declaration.
Instead of the forward declaration
class B;
you can define an interface like
struct I_whoop
{
virtual void whoop_whoop() = 0;
};
then let class B implement that interface, and just use a pointer to the interface.
Actually You can not if using concrete class.
But You can achieve your goal by using template parameters. Making class B a template parameter of template class A.
How can I make it so that I don't have to prototype B in order to have a pointer to a B object in class A?
Like this:
class A
{
private:
int an_int;
class B *something_else;
public:
A(int n) : an_int(n), something_else(nullptr) {}
};
class B
{
private:
int an_int;
class A *something_else;
public:
B(int n) : an_int(n), something_else(nullptr) {}
};
In C and C++ it has never been necessary for a type T to be
forward declared before the declaration of objects of type T *
(or const variants), because the declaration of a T * per se requires
the compiler only to know the size of a T *, not the size or definition
of a T, and the size of a T * is the same, regardless of T.
Here is a more fleshed-out illustration:
class A
{
private:
int an_int;
class B *something_else;
public:
A(int n, class B * pb = nullptr) : an_int(n), something_else(pb) {}
int get_int() const {
return an_int;
}
void set_B(class B * pb) {
something_else = pb;
}
class B * get_B() const {
return something_else;
}
};
class B
{
private:
int an_int;
class A *something_else;
public:
B(int n, class A * pa = nullptr) : an_int(n), something_else(pa) {}
int get_int() const {
return an_int;
}
void set_A(class A * pa) {
something_else = pa;
}
class A * get_A() const {
return something_else;
}
};
#include <iostream>
int main()
{
A a(1);
B b(2);
a.set_B(&b);
b.set_A(&a);
std::cout << a.get_B()->get_int() << std::endl;
std::cout << b.get_A()->get_int() << std::endl;
return 0;
}
Output:
2
1
(gcc 4.9.2/clang 3.5.2 -std=c++11 -Wall -pedantic)
I would like to be able to provide to the base class MCFormater a formatting method that would work for different types (uint32, uint8...)
class MCFormater {
public:
MCFormater() {}
virtual ~MCFormater() {}
virtual mcc_t Gen();
protected:
template<typename K> //here is the problem
virtual void Format(K& a, const K& b) = 0;
//...
uint32_t a;
uint8_t b;
void Foo();
};
void MCFormater::Foo() {
Format<uint32_t>(a, 3); //I want to be able to call for Format
Format<uint8_t>(b, 3); //with uint32_t, and uint8_t, and more
}
class GFormater : public MCFormater {
GFormater() {}
template<typename K>
virtual void Format(K& a, const K& b) {
a = b;
}
};
class EFormater : public MCFormater {
EFormater() {}
template<typename K>
virtual void Format(K& a, const K& b) {
a |= b;
}
};
but I get the error: templates may not be 'virtual'.
what is the right way to do it? (is there one?)
Modify...
class MCFormater {
public:
MCFormater() {}
virtual ~MCFormater() {}
virtual mcc_t Gen();
protected:
template<typename K> //here is the problem
virtual void Format(K& a, const K& b) = 0;
//...
uint32_t a;
uint8_t b;
void Foo();
};
void MCFormater::Foo() {
Format<uint32_t>(a, 3);
Format<uint8_t>(b, 3);
}
class GFormater : public MCFormater {
GFormater() {}
template<typename K>
virtual void Format(K& a, const K& b) {
a = b;
}
};
class EFormater : public MCFormater {
EFormater(FTEKeeps* keeps) : MCFormater(keeps) {}
template<typename K>
virtual void Format(K& a, const K& b) {
a |= b;
}
};
To...
#include<iostream>
using namespace std;
template<typename K>
class MCFormater {
public:
MCFormater() {}
virtual ~MCFormater() {}
virtual mcc_t Gen();
protected:
virtual void Format(K& a, const K& b) = 0;
//...
uint32_t a;
uint8_t b;
void Foo();
};
template<typename K>
void MCFormater<K>::Foo() {
Format<uint32_t>(a, 3);
Format<uint8_t>(b, 3);
}
template<typename K>
class GFormater : public MCFormater<K> {
GFormater() {}
virtual void Format(K& a, const K& b) {
a = b;
}
};
template<typename K>
class EFormater : public MCFormater<K> {
EFormater(FTEKeeps* keeps) : MCFormater<K>(keeps) {}
virtual void Format(K& a, const K& b) {
a |= b;
}
};
Explanation: Member function templates cannot be virtual. If this was allowed then the linker would have to add a new entry to the virtual table every time the Format function was called with a different type. Dynamic linking would be unacceptably complicated.