Forward declarations that involve std::vector, etc - c++

I have used forward declarations a lot; they help avoid many #includes, improve compilation time and what not. But what if i want to forward-declare a class in the standard library?
// Prototype of my function - i don't want to include <vector> to declare it!
int DoStuff(const std::vector<int>& thingies);
I have heard it's forbidden/impossible to forward-declare std::vector. Now this answer to an unrelated question suggests to rewrite my code this way:
stuff.h
class VectorOfNumbers; // this class acts like std::vector<int>
int DoStuff(const VectorOfNumbers& thingies);
stuff.cpp
// Implementation, in some other file
#include <vector>
class VectorOfNumbers: public std::vector<int>
{
// Define the constructors - annoying in C++03, easy in C++11
};
int DoStuff(const VectorOfNumbers& thingies)
{
...
}
Now, if i use VectorOfNumbers instead of std::vector<int> in all contexts throughout my project, everything is going to be good, and i don't need to #include <vector> in my header files anymore!
Does this technique have major disadvantages? Can the gain of being able to forward-declare vector outweigh them?

If you ever delete a VectorOfNumbers as a std::vector<int> (and since you used public inheritance this conversion is implicit) you've entered the realm of undefined behavior. This is probably more likely to accidentally happen than one might suspect.
I've never personally noticed significant compilation slowdown from just including vector where needed, but if you really want to isolate the include, use a client API interface that doesn't know about the underlying container type (vector) and pimpl the vector include into a single source file.

The reason I wouldn't do this:
const std::vector<int>& a = a_3rd_party_lib::get_data(); // this type is out of your control
DoStuff(a); // you cannot pass it to this function!

You include <vector> in your header file. The <vector> header will have been built to prevent multiple inclusions, so you just include it everywhere you need it.

This works well for the interface for a class, but not for the implementation. If your class has any vector members you must #include <vector> or the class definition will not compile.

Instead of inheritance, you could use composition:
// Implementation, in some other file
#include <vector>
class VectorOfNumbers
{
public:
std::vector<int>& container;
VectorOfNumbers(std::vector<int>& in_container)
: container(in_container)
{
}
};
int DoStuff(const VectorOfNumbers& thingies)
{
std::sort(thingies.container.begin(), thingies.container.end());
// ...
}
The downside is the extra variable name on every access.
Also, you'd need this implementation to be in a header file included by cpps so they will know what they can do with VectorOfNumbers.
Essentially, just making a wrapper for your vector. This is like a light-weight version of PImpl (we only care about avoiding header dependencies so we don't need the full pointer decoupling). It avoids the issues raised by Mark B and ybungalobill.
But I don't think it's really worth it.

Related

How is it that a forward declaration can hide a dependency and cause user code to skip a necessary recompilation? (google style guide c++)

Forward declarations can hide a dependency, allowing user code to skip necessary recompilation when headers change.
from https://google.github.io/styleguide/cppguide.html#Forward_Declarations
I have learned recently there is some debate over whether to use a forward declare or just include the header within the header itself. At work we forward declare our internal classes (not library code) and include the headers containing those classes in the corresponding .cpp. If the code in the .cpp never uses the class then the include can be skipped entirely; eg it passes a type.
say we have the following code and files
#pragma once
//test.h
class Test{
public:
void foo() const;
};
//test.cpp
#include<iostream>
#include "test.h"
void Test::foo() const
{
std::cout << "test" << std::endl;
}
#pragma once
//worker_function.h
class Test;
void doWork(const Test&);
//worker_function.cpp
#include"worker_function.h"
#include"Test.h"
void doWork(const Test& obj){
obj.foo(); //must include for compilation
}
#pragma once
//myclass.h
class Test;
class MyClass{
public:
void passthrough(const Test& obj);
};
//myclass.cpp
#include "myClass.h"
#include "worker_function.h"
void MyClass::passthrough(const Test& obj){
doWork(obj);
}
MyClass never actually needs to know the size of Test to get to doWork(). So, we don't need an include of Test.h. Only the actual function that does work (doWork) will need to include within its cpp. By using forward declarations, changes to Test.h will not cause any recompilation of MyClass.cpp. But in my view this is a good thing, because it is not a necessary recompilation.
Disclaimer: The google style guide has an example related to void*, but I'm not sure it is related to this bullet point; as it is just an incorrect function call rather than a necessary recompilation. Also, I believe that particular example would be eliminated if the function was defined in the .cpp instead and they included the appropriate classes. Additionally, if it is related to the bullet I have in this question, mitigation of issues related to void* do not sound valid enough to forbid the use of forward declarations entirely.
So, my question is -- is there any concrete example of a case where it will skip a necessary recompilation?
edit:
This is not a duplicate of linked post as that answer only includes a void* response. I stated in this question that I am looking for any other example from the void* given. IMO that is a pretty esoteric issue (hopefully isn't common in modern c++) to completely throw out using forward declarations entirely. It seems to me like creating a rule to never use references, including pass by reference, because class member references can easily yield dangling references via default copy

c++ Forward Declaration design

From what i've read, i should use forward declarations whenever I can. I have classes like this ( where every fields are pointers because of forward declarations ) :
class A
{
// ...
A* a;
B* b;
C* c;
D* d;
E* e;
};
But there is problems with that.
1- This implies to call new and delete ( or at least new with smart pointers ) for every fields in constructor, while stack allocated fields don't need this.
2- I've read that stack allocation was faster than heap allocation.
3- Also that means that almost every fields on every classes should be pointers.
Am I doing the right way doing like my example class? Or am I missing something with forward declarations?
The example you've shown is an overkill. The suggestion to use forward declarations doesn't mean your code design is driven by forward declaration practices. Forward declarations are just implementation detail, the design prevails.
First decide whether you need aggregation or composition, then whether the forward declaration is appropriate.
Do prefer forward declaration over #include when the forward-declared type is part of your method signature, i.e. a parameter's type.
#include "OtherClass.h" // 'bad' practice
class OtherClass; // this is better than #include
....
class MyClass
{
void method(OtherClass *ptr);
}
It's not an absolute rule anyway as it's not always possible/convenient to use forward decls instead of includes.
The implication is inverse - you're not supposed to use pointers just in order to use forward declarations, but you're suppose to use forward declarations after you've taken a design decision (such as using pointers instead of objects as members) when you can.
So if it makes more sense to use objects, do so, and include the files you need. Don't use pointers just so you can forward-declare the classes.
If you are using pointers as members, prefer forward declaration than exposing complete class definition. Don't use pointers just to meet some rule blindly.
Technically spoken, you can (and should!) use a forward declaration, if the interface of your class doesn't depend on a fully qualified type. The compiler has to reserve enough space for members and add management functions at compile time - just using pointers or references in your class does not introduce dependencies on types.
BTW: Forward declaration isn't that new: In some C standard libraries, FILE is a typedef for a forward declared struct, which makes sense since FILE is always used for pointers in the whole public file API.
Use pointers or references for objects that the class doesn't own. But for objects that are owned by this class don't use forward declarations as a reason for choosing pointers.
If you really want to minimize compile time dependencies consider the PIMPL idom rather than turning all your members into pointers:
MyClass.h:
#include <memory>
class MyClassImpl;
class MyClass {
public:
MyClass();
~MyClass();
void doThing();
private:
std::unique_ptr<MyClassImpl> pimpl_;
};
MyClass.cpp
#include "MyClass.h"
#include "MyClassImpl.h"
MyClass::MyClass() { } // in .cpp so unique_ptr constructor has complete type
MyClass::~MyClass() { } // in .cpp so unique_ptr destructor has complete type
void MyClass::doThing(){
pimpl_->doThing();
}
MyClassImpl.h:
#include "A.h"
#include "B.h"
class MyClassImpl {
private:
A a_;
B b_;
public:
void doThing();
};
MyClassImpl.cpp:
#include "MyClassImpl.h"
void MyClassImpl::doThing() {
// Do stuff with a_, b_, etc...
}
This might not address performance concerns as you still have dynamic memory allocation but you would have to measure it to see.
In addition to the good answers already given: In cases where your class doesn't create an object but uses it privately (for instance some utility class), references can be used instead of pointers.
class UtilityClass; // forward declaration (even interfaces make sense here)
class MyClass {
public:
/// takes an UtilityClass for implementing some of its functions
MyClass(UtilityClass& u): util(u) {}
private:
UtilityClass& util;
// ...more details
};
These are cases, where forward declaration doesn't mean that objects have to be created on heap (as for your problems #1 and #2).

Define a Forward-defined C++ struct by aliasing

I want to write a C-wrapper around an existing C++ codebase. So I need to implement some C-API functions that merely forward their operations to the corresponding C++ methods.
My problem is, I cannot figure out how to implement a forward-defined struct by means of an existing class:
//Foo.hpp
namespace myLib {
struct Foo {
//some meaningful C++ body
};
}
//foo.h
//#ifdef __cplusplus etc. left out
extern "C" {
struct myLib_foo;
myLib_foo* mkfoo();
//etc.
}
//foo.cpp
extern "C" {
#include "Foo.hpp"
#include "foo.h"
typedef myLib_foo myLib::Foo; //this does not work
myLib_foo* mkfoo() { return new myLib::Foo(); }
}
In this situation, the C-API can and shall only work with pointers to myLib::Foo, which obviously works well, if I define myLib_foo as a new struct inside foo.cpp. I guess it also works, if I define a struct myLib_foo somewhere else. Yet, since I want to keep my namespaces manageable, I am searching a way to define myLib_foo to be equivalent to some existing (and completely defined) struct. This, however does not work, since my compiler refuses the code above with "typedef redefinition with different types". Apparently, it distinguishes between type-aliases and structs.
Is there even a way to achieve what I want or does C++ have no means for real type-aliases?
edit:
By the answer below, I figured I can use inheritance plus static_cast:
//foo.cpp
extern "C" {
#include "Foo.hpp"
#include "foo.h"
struct myLib_foo : public myLib::Foo {}; //this does work
myLib_foo* mkfoo() { return static_cast<myLib_foo*>(new myLib::Foo()); }
}
The C code does not ever need a definition of the struct myLib_foo that it sees.
It handles it only through pointers and functions.
On the C++ side a simple implementation is a struct containing a pointer to the "real" object that it represents. You then define it in the ordinary way (in the C++ code), but of course with the name already established for the C code usage.
If you want to avoid even that little inefficiency, to hand out real object pointers to the C code, well then you have essentially two options:
reinterpret_cast, or
static_cast with the not-quite-C struct as a (possibly empty) base class.
But I would go for the simple implementation of myLib_foo as a struct with a pointer to the real one. The KISS principle: Keep It Simple, Stupid*. On second thoughts, to avoid allocation and deallocation issues, and to also avoid a formal dependency on the compiler (even if that would just be academic, a formality), I would go for the static_cast. For thinking about what it all entails, this seems simplest.
*: Oh, the last few times I mentioned this principle on SO, those answers were heavily downvoted. That has also happened when I have (correctly) proposed macros as solutions. I think one should be technically honest and ignore the general SO readership, so I mention it anyway.

c++11 class member array size constexpr forward declaration

I want to exclude some headers from my include chain after having used them. From what I know there is no exclude "header.h" in c++11.
Pseudo Code Wishful thinking:
#include "the_bad_header.h" //long includechain with later unused declarations
class bulky { ... };
constexpr std::size_t bulkysize = sizeof(bulky);
forget everything included and class bulky and remember only bulkysize
My example where the problem becomes evident follows. Please don't argue this is not a serious problem. The Example is broken down to show the minimal abstract language usage. I will describe the old fashioned solutions and their disadvantages too.
Old style solution
justanotherheader.h:
class bulkywrap
{
public:
bulkywrap();
protected:
friend class bulkywrap_pImpl;
bulkywrap_pImpl *const pImpl; //opaque pointer, private implementation
};
justanothercppunit.cpp:
#include "justanotherheader.h"
#include "boost/lotsofheaders.hpp"
//#include more and more headers of highly complex libraries so adding millions of known types and other identifiers, macros, and so on
class bulkywrap_pImpl
{
//lots of members of types used from the other libraries
};
bulkywrap::bulkywrap()
: pImpl( new bulkywrap_pImpl() )
{}
My current Solution
justanotherheader.h:
#include "stdint.h" // this is the only header I like to use, but also unnecessary.
#define UNKNOWNSIZE 12345
class bulkywrap
{
public:
bulkywrap();
protected:
friend class bulkywrap_pImpl;
bulkywrap_pImpl *const pImpl; //opaque pointer, private implementation
uint8_t pImpl_Placement[UNKNOWNSIZE]; //placement new for pImpl
};
justanothercppunit.cpp:
#include "justanotherheader.h"
#include "boost/lotsofheaders.hpp"
//#include more and more headers of highly complex libraries so adding millions of known types and other identifiers, macros, and so on
class bulkywrap_pImpl
{
//lots of members of types used from the other libraries
};
bulkywrap::bulkywrap()
: pImpl( new(this->pImpl_Placement) bulkywrap_pImpl() ) //using this here is safe
{}
So, the code above is working. The advantages are: hiding complexity and having no runtime dynamic memory indirections. Huh? I mean, the placement new allows the whole object to be put on stack and all member addresses are known at compile time. My attempt is to have best performance while using interface design of opaque pointer.
If you think: "this performance advantage is not worth the thinking effort." then please leave that question.
My expected Solution
justanotherheader.h:
#include "stdint.h" // this is the only header I like to use, but also unnecessary.
constexpr std::size_t get_bulkywrap_pImpl_Size( void ); //constexpr function forward declaration
extern constexpr std::size_t bulkywrap_pImpl_Size; //constexpr literal forward declaration with external initialization
class bulkywrap
{
public:
bulkywrap();
protected:
friend class bulkywrap_pImpl;
bulkywrap_pImpl *const pImpl; //opaque pointer, private implementation
uint8_t pImpl_Placement[get_bulkywrap_pImpl_Size()]; //undefined constexpr used
uint8_t pImpl_Placement[bulkywrap_pImpl_Size]; //alternative to above. undefined constexpr used
};
justanothercppunit.cpp:
#include "justanotherheader.h"
#include "boost/lotsofheaders.hpp"
//#include more and more headers of highly complex libraries so adding millions of known types and other identifiers, macros, and so on
class bulkywrap_pImpl
{
//lots of members of types used from the other libraries
};
constexpr std::size_t get_bulkywrap_pImpl_Size( void )
{
return sizeof(bulkywrap_pImpl);
}
constexpr std::size_t bulkywrap_pImpl_Size = sizeof(bulkywrap_pImpl);
bulkywrap::bulkywrap()
: pImpl( new(this->pImpl_Placement) bulkywrap_pImpl() ) //using this here is safe
{}
In my current solution I need to verify the sizeof(bulkywrap_pImpl) and adjusting UNKNOWNSIZE manually.
I think it is currently not possible to get any information from a compilationunit to others. I know this is typically intended by good reason, but this limits the possibilities of c++11.
I want to point out:
jtc1 sc22 wg21 paper n3337
jtc1 sc22 wg21 paper n3308
Please help me to find information weather and why the standard does not allow this.
But furthermore I would like to find a solution of how to export some literal constant during compiliation time out of a compileunit into another compileunit. It's just a literal, so all statements and expressions are not affected by it. Thus compilation does not depend where the size of the array comes from.
My suggestion results in some work for the ISO-jtc1-sc22-wg21 and the compiler developers, but I don't see any relevant difference between template and constexpr since every definition must appear in the same translationunit. This makes modular programming and clean interfaces bogus.
And no: I don't want to use preprocessor macros, dynamic new or virtual member functions. Of importance is maximal const-correctness, since the size of the class is const.
Please help
you can't have both "compile-time" and "from another compilation unit" at the same time. also it's not clear why do you need to forget successfully parsed header. parsing time already consumed. i suggest you to create another header with size constant, include it from both files, and add static_assert to pimpl file, checking that constant >= sizeof(pimpl). you can generate this header as part of your build system by compiling source file including pimpl and doing cout <<sizeof(pimpl). also i suggest you to not waste time and space for pimpl pointer and replace it with member function, returning address of properly cast buffer. also you failed to show where you call pimpl's destructor. also implementing assignment/copy/move/swap will be a lot of fun
use static_assert in cpp to check that size declared in header >= size of impl class

Forward declare a standard container?

Is it possible to forward declare an standard container in a header file? For example, take the following code:
#include <vector>
class Foo
{
private:
std::vector<int> container_;
...
};
I want to be able to do something like this:
namespace std
{
template <typename T> class vector;
}
class Foo
{
private:
std::vector<int> container_;
...
};
Can this be done?
Declaring vector in the std namespace is undefined behavior. So, your code might work, but it also might not, and the compiler is under no obligation to tell you when your attempt won't work. That's a gamble, and I don't know that avoiding the inclusion of a standard C++ header is worth that.
See the following comp.std.c++.moderated discussion:
forward declaring std::vector. Works, but is it legal and standard compliant?
I don't think so because the compiler would have no way of knowing how much space to allocate for the container_ object. At best you could do:
std::vector<int> *container_;
and new it in the constructor, since the compiler knows the size of a pointer.
Apart from what the others said, you may find it useful to know that there is a sanctioned way of forward-declaring iostreams and some related templates: The header <iosfwd>. It would be useful if the standard had more such headers.