Forward Declarations of recursive templates using Boost::Units - c++

as i am seeking to reduce the compile times of our code, i am currently trying to reduce heavy includes in header files. For this, i am forward declaring function parameters as in this example:
// Class A.h
class B;
class A
{
...
void foo(B);
}
However, i did not find a way to forward declare our typedefinitions, that rely on boost units such as the definition of a length unit (Length.h) required as a function parameter in the file Object.h:
// Length.h
using meter_unit = boost::units::si::meter_base_unit::unit_type;
using Length = boost::units::quantity<meter_unit, double>;
BOOST_UNITS_STATIC_CONSTANT(Meter, meter_unit);
BOOST_UNITS_STATIC_CONSTANT(Meters, meter_unit)
// Object.h
#include <Length.h> // This include shall be avoided
class Position;
class Object {
...
bool isNearby(Position pos, Length distance);
}
Are there any suggestions on how i could achieve this?
What I Tried:
First Approach: I tried forward declaring the template boost::units::quantity<meter_unit, double>;
but i struggeld to define the meter_unit that contains both template class meter_base_unit and unit_type inside the namespace of meter_unit.
The meter_base_unit is defined inside boost units as below (simplified) and i guess the unit_type is defined inside the macro BOOST_TYPEOF_REGISTER_TYPE.
// Boost ... Units/Meter.hpp
namespace boost::units::si {
struct meter_base_unit : public base_unit<meter_base_unit, length_dimension, -9>
{
static std::string name() { return("meter"); }
static std::string symbol() { return("m"); }
};
}
}
BOOST_TYPEOF_REGISTER_TYPE(boost::units::si::meter_base_unit)
Is such a constellation even possible to forward declare? And if not, do alternatives exist that could have the same benefit (avoided include while still using the Boost Units Library).
Second Approach: Defining classes that inherit from the respective units such as:
class Length : public boost::units::quantity<meter_unit, double>
but the problem is, that i then have to create CTR for every possible unit that i try to initialize the Length unit with (Feet, Meter, Kilometer a.s.o), which is basically re-implementing the library.
Third Approach: Creating a class that contains only the length unit as a variable, which then leads to overloading all possible operators for that class.
I am happy for every contribution regarding my specific problem and every contribution leading to deeper understanding of template forward declarations.
Thanks in Advance
SegfaultCreator

Related

c++ metaprogramming: creating typedef for each enum type member as type

I wonder if it is possible to generate types set from enum class for the metaprogramming purposes.
I'm originally a C# programmer and used to using a lot of attributes for reflection and metaprogramming. For example, it is a general pattern for me to write a snippet like that with C#:
public enum ComponentEnum { Component1, Component2, Component3 }
[Component(ComponentEnum.Component1)]
public class Component1
{
/* Some code */
}
public static class ComponentsMeta
{
private static Dictionary<Type, ComponentEnum> map;
static ComponentMeta() { /*process the whole codebase via reflection, search Component marked classes an fill the map */}
public static bool IsComponent<T>() => map.ContainsKey(typeof(T));
public static int GetComponentUID<T>() => (int)map[typeof(T)];
}
Of course, it is a very basic snippet without asserts and some other stuff but I believe you got the idea.
I want to make the same behavior in the c++ snippet. What I want to do exactly is makes a type called Components that will contain some utility functions like bool Components::isComponent<T>() or size_t Components::getComponentUID<T>() or some related stuff. The best way I've seen so far is to write it down by myself, making a metaclass like
template <typename Ts..>
class ComponentsData
{
/* functions impl here */
}
typedef ComponentsData<C1, C2, C3> Components;
So, now I can ask Components<C1>::getComponentUID() and it returns me uid of that component (depends on its position as template parameter or constexpr value of that component, it doesn't matter). But it is a very inconvenient way to do that and I wonder if I can put a macro inside the component class or using attributes and code generation step or something. In other words, my goal is to mark somehow the class that it should be in that components set and use it later. What c++ can offer for that purpose?
It will be okay if I could make something like I did C# way - make an enum class, list all the components there, and write a constexpr value inside a component class (or somewhere near the enum class, both ways is good for me).
I mean something like that:
/* ComponentsEnum.h */
enum class ComponentsEnum { Comp1, Comp2, Comp3 };
// Here is some magic to generate Components<C1, C2, C3> metaclass.
/* another file */
#include "ComponentsEnum.h"
struct C1 { const ComponentsEnum MyValue = ComponentsEnum::Comp1; };
or something like that
/* ComponentsEnum.h */
enum class ComponentsEnum { Comp1, Comp2, Comp3 };
// Here is all the magic
// All enum members concats into `Components<Comp1, Comp2, Comp3, ...>`
ConcatAll<ComponentsEnum>();
/* another file */
#include "ComponentsEnum.h"
struct Comp1 { };
or maybe something with macro magic:
/* ComponentsEnum.h */
enum class ComponentsEnum { Comp1, Comp2, Comp3 };
#define InitMeta(ComponentsEnumMember) /* Some Magic */
/* another file */
#include "ComponentsEnum.h"
struct Comp1 { InitMeta(ComponentsEnum::Comp1) };
Thanks in advance!
Following on my comment.
You could do something like this in C++17:
// In register.hpp
int register_me();
// In register.cpp
int register_me(){
static int id = 0;
return id++;
}
// In wherever.hpp
// #include "register.hpp"
struct component{
inline static int id = register_me();
};
Pre-C++17 requires moving the definition and initialization to a .cpp for each component::id.
But I strongly recommend not to use this. Rethink your design, converting types to IDs is a code smell for me. C++ is not really designed to do such things, it can haunt you later.
The code above relies on dynamic initialization of all static variable at the start of the program. The order is unspecified, each compilation might result in assignment of different IDs.
Definitely do not put this into any shared libraries before being 100% sure you know how the compilation, linking, and loading processes work for your toolchain because these are outside the scope of C++ Standard.
Thanks to the #JerryJeremiah link and #Quimby advice, I found the solution.
So, I was misled by my C# habits and the idea was quite simple but tricky.
According to the difference between C# generics and C++ templates, generics are runtime instanced types, but templates are compile-time types. So, I do not need to create a map or process the whole codebase, all I need will be generated with templates in compile time.
The solution itself:
I want an enum to generate continuous uid numbers for my components. So, define it:
enum class ComponentEnum
{
C1,
C2,
C3
};
I want a simple interface for my Components to ask for meta information. Define it too:
struct Components
{
template<typename T>
static bool isComponent() { /* Some stuff here */ }
template<typename T>
static int getComponentUID() { /* Some stuff here */ }
};
Now I can ask uid with one simple generalized call Components::getComponentUID<MyComponent>(). Nice.
The real magic. I've created template metaclass and macro to create a typedef and some additional methods:
template <typename T, ComponentEnum enumMember>
struct ComponentMeta
{
static constexpr bool isComponent = true;
static constexpr int uid = static_cast<int>(enumMember);
};
#define ComponentMetaMacro(type_name, enum_name) typedef ComponentMeta<type_name, ComponentEnum::enum_name> Meta; \
static const char* toString() { return #type_name; }
So I can fill methods from my interface with simple forwarding to that metaclass:
struct Components
{
template<typename T>
static bool isComponent() { return T::Meta::isComponent; }
template<typename T>
static int getComponentUID() { return T::Meta::uid; }
};
All things left is include header with metaclass and macro and call the macro:
struct C1
{
ComponentMetaMacro(C1, C1)
};
struct C2
{
ComponentMetaMacro(C2, C2)
};
Run a few tests:
std::cout << C1::toString() << ": " << Components::getComponentUID<C1>() << std::endl;
std::cout << C2::toString() << ": " << Components::getComponentUID<C2>() << std::endl;
C1: 0
C2: 1
Yay!
This solution has three main problems:
isComponent() becomes the static assert instead of the flag. I mean, the code won't compile if T-type is not a component. It is quite ok but smells.
It is a single linked meta. I can't get a component type from the index, only an index from the type. But for serialization purposes, it could be useful to have a backlink.
I should include the enum class to every component header. It means there will be a huge compile-time affect when I will add a new enum member. I suppose there is a way to avoid it but can't see one. The only enum class purpose is to have the smallest index as possible for every component that will be static between compilations. Maybe I have to think about some data generation or another approaches, but for the small project it is ok.

Minimizing the amount of header files needed using the Builder/Fluent pattern

I am experimenting with the Builder/Fluent style of creating objects trying to extend some ideas presented in a course. One element I immediately didn't like with my test implementation was the large number of additional header files the client needs to include for the process to work, particularly when I wish to make use of public/private headers via the pImpl idiom for purposes of providing a library interface. I'm not entirely certain whether the problem lies with my implementation or I'm just missing an obvious 'last step' to achieve what I want.
The general gist is as follows (using the toy example of Pilots):
Firstly the client code itself:
(Note: for brevity, various boilerplate and irrelevant code has been omitted)
Pilot p = Pilot::create()
.works().atAirline("Sun Air").withRank("Captain")
.lives().atAddress("123 Street").inCity("London")
What's happening here is:
In Pilot.h, the Pilot class is defined with a static member method called create() that returns an instance of a PilotBuilder class defined in PilotBuilder.h and forward declared in Pilot.h
Essentially the PilotBuilder class is a convenience builder only used to present builders of the two different facets of a Pilot (.works() and .lives()), letting you switch from one builder to another.
Pilot.h:
class PilotBuilder;
class Pilot {
private:
// Professional
string airline_name_, rank_;
// Personal
string street_address_, city_;
Pilot(){}
public:
Pilot(Pilot&& other) noexcept;
static PilotBuilder create();
friend class PilotBuilder;
friend class PilotProfessionalBuilder;
friend class PilotPersonalBuilder;
};
Pilot.cpp:
#include "PilotBuilder.h"
PilotBuilder Pilot::create() {
return PilotBuilder();
}
// Other definitions etc
PilotBuilder.h
#include "public/includes/path/Pilot.h"
class PilotProfessionalBuilder;
class PilotPersonalBuilder;
class PilotBuilder {
private:
Pilot p;
protected:
Pilot& pilot_;
explicit PilotBuilder(Pilot& pilot) : pilot_{pilot} {};
public:
PilotBuilder() : pilot_{p} {}
operator Pilot() {
return std::move(pilot_);
}
PilotProfessionalBuilder works();
PilotPersonalBuilder lives();
};
PilotBuilder.cpp
#include "PilotBuilder.h"
#include "PilotProfessionalBuilder.h"
#include "PilotPersonalBuilder.h"
PilotPersonalBuilder PilotBuilder::lives() {
return PilotPersonalBuilder{pilot_};
}
PilotProfessionalBuilder PilotBuilder::works() {
return PilotProfessionalBuilder{pilot_};
}
As you can imagine the PilotProfessionalBuilder class and the PilotPersonalBuilder class simply implement the methods relevant to that particular facet eg(.atAirline()) in the fluent style using the reference provided by the PilotBuilder class, and their implementation isn't relevant to my query.
Avoiding the slightly contentious issue of providing references to private members, my dilemma is that to make use of my pattern as it stands, the client has to look like this:
#include "public/includes/path/Pilot.h"
#include "private/includes/path/PilotBuilder.h"
#include "private/includes/path/PilotProfessionalBuilder.h"
#include "private/includes/path/PilotPersonalBuilder.h"
int main() {
Pilot p = Pilot::create()
.works().atAirline("Sun Air").withRank("Captain")
.lives().atAddress("123 Street").inCity("London");
}
What I cannot figure out is:
How do I reorder or reimplement the code so that I can simply use #include "public/includes/path/Pilot.h" in the client, imagining say, that I'm linking against a Pilots library where the rest of the implementation resides and still keep the same behaviour?
Provided someone can enlighten me on point 1., is there any way it would be then possible to move the private members of Pilot into a unique_ptr<Impl> pImpl and still keep hold of the static create() method? - because the following is obviously not allowed:
:
PilotBuilder Pilot::create() {
pImpl = make_unique(Impl); /* struct containing private members */
return PilotBuilder();
}
Finally, I am by no means an expert at any of this so if any of my terminology is incorrect or coding practices really need fixing I will gladly receive any advice people have to give. Thank you!

Nested classes definition and initiation through files

I'm trying to make class functions I can tack on to other classes, like with nested classes. I'm still fairly new to C++, so I may not actually be trying to use nested classes, but to the best of my knowledge that's where I'm at.
Now, I've just written this in Chrome, so it has no real use, but I wanted to keep the code short.
I'm compiling on Windows 7, using Visual Studio 2015.
I have two classes in file_1.h:
#pragma once
#include "file_2.h"
class magic_beans{
public:
magic_beans();
~magic_beans();
int getTotal();
private:
double total[2]; //they have magic fractions
}
class magic_box{
public:
magic_box(); //initiate
~magic_box(); //make sure all objects have been executed
void update();
magic_beans beans; //works fine
magic_apples apples; //does not work
private:
int true_rand; //because it's magic
};
... And I have one class in file_2.h:
#pragma once
#include "file_1.h"
class magic_apples{
public:
magic_apples();
~magic_apples();
int getTotal();
private:
double total[2];
}
Now, I've found that I can simply change:
magic_apples apples;
To:
class magic_apples *apples;
And in my constructor I add:
apples = new magic_apples;
And in my destructor, before you ask:
delete apples;
Why must I refer to a class defined in an external file using pointers, whereas one locally defined is fine?
Ideally I would like to be able to define magic_apples the same way I can define magic_beans. I'm not against using pointers but to keep my code fairly uniform I'm interested in finding an alternative definition method.
I have tried a few alternative defines of magic_apples within my magic_box class in file_1.h but I have been unable to get anything else to work.
You have a circular dependency, file_1.h depends on file_2.h which depends on file_1.h etc. No amount of header include guards or pragmas can solve that problem.
There are two ways of solving the problem, and one way is by using forward declarations and pointers. Pointers solve it because using a pointer you don't need a complete type.
The other way to solve it is to break the circular dependency. By looking at your structures that you show, it seems magic_apples doesn't need the magic_beans type, so you can break the circle by simply not includeing file_1.h. So file_2.h should look like
#pragma once
// Note no include file here!
class magic_apples{
public:
magic_apples();
~magic_apples();
int getTotal();
private:
double total[2];
}

Separate enum declaration and definition in C++11

There are several questions on these forums about the inheritance of C++ enums for extending (which is actually the thing without the logic). But what about inheritance just for setting specific values?
Currently, there is something like the following in my code:
//lib_impl.h
enum class X {
a = 13, // these values are
b = 42 // implementation dependent
}
//lib.h
#include "lib_impl.h"
void some_func(X param) {
X x = X::a;
}
I just want to avoid the dependecy of the 'lib' from its implementation. Probably, something other than enums must be used for that. As even in C++11 we have the ability only to declare forward enum name, but not its enumerators:
//lib.h
enum class X { a, b } // this is both declaration and definition, unfortunately
void some_func(X param) {
X x = X::a;
}
//lib_impl.h
#include "lib.h"
enum class X { // redefenition, compilation error
a = 13,
b = 42
}
What is the best compile-time solution for such problems?
--
As it seems to be unimplementable in c++, what is the most common way to resolve such issues? Leave the dependency of the 'lib' from the 'impl' as it is? Probably, 'impl' could be split into two parts, small which will be included before the 'lib.h' and other, bigger, to be included after it. Is it ok or I need to abandon the use of enums in favor of abstract classes?
Expose an enum with nominal values (start with 0, sequential say). Inside your library, remap these values to an internal enum with implementation dependent values (say an array for speed, using the external value as index). Reverse the mapping if you export said enum values to the outside (the reverse mapping will be slower).

In C++, how can I avoid #including a header file when I need to use an enumeration?

In my C++ header files I try to use forward declarations (class MyClass;) instead of #including the class header, as recommended in many C++ coding standards (the Google C++ Style Guide is one).
Unfortunately, when I introduce enumerations, I can't do the forward declaration any more. Like this:
//// myclass1.hpp ////
class MyClass1
{
enum MyEnum1
{
Enum_A, Enum_B, Enum_C
};
};
//// myclass2.hpp ////
// I want to avoid this
#include "myclass1.hpp"
// I'd prefer to do this (forward declaration)
class MyClass1;
class MyClass2
{
// This is o.k.: I only need to forward declare MyClass1
MyClass1* ptr;
// This forces me to #include, but I don't want to!
void func( MyClass1::MyEnum1 e );
};
The best solution I can think of so far is to replace enums with member constants:
//// myclass1.hpp ////
MyClass1
{
static const int Enum_A;
static const int Enum_B;
static const int Enum_C;
};
//// myclass1.cpp ////
const int Enum_A = 1;
const int Enum_B = 2;
const int Enum_C = 3;
In this case, though, the solution seems worse than the problem.
I'm currently looking through Large Scale C++ Software Design (Lakos) and Working Effectively with Legacy Code (Feathers) for dependency breaking techniques, but I haven't found a good solution yet.
This is difficult to do nicely. Perhaps moving enums to a common header file would be a reasonable solution?
Edit: I know the question asked to avoid including a header file, but there's just no way (AFAIK) to do this. Moving enums to a separate header file at least minimises the amount of stuff in the header file you do need to include. It's certainly better than the craziness suggested in the question!
You cannot forward declare enum values - and your workaround is a step down the path to complete madness.
Are you experiencing any major compilation slowdowns caused by #including headers? If not, just #include them. Use of forward declarations is not "best practice" it is a hack.
You can use forward declarations only when you are declaring a pointer. If you are declaring a non-pointer variable, you will have to include the relevant header file.
Since an enum variable is not a pointer you can't use forward declarations. And I don't think there's an alternative solution.
C++0x's strongly typed enums can be forward declared. GCC 4.4.0 and CodeGear C++Builder 2009 support strongly typed enums.
There are a few enum-like classes floating around like the (proposed but never finalized and accepted) Boost.Enum available for download from the Boost Vault at this link. Since Boost.Enums are classes, they can be forward declared.
However, just putting enums in a separate file (as in this answer) seems the simplest, best solution (barring C++0x suport).
You can use template arguments to program against 'general' enum types. Much like this:
// enum.h
struct MyClass1 { enum e { cE1, cE2, cELast }; };
// algo.h
// precondition: tEnum contains enumerate type e
template< typename tEnum > typename tEnum::e get_second() {
return static_cast<typename tEnum::e>(1);
}
// myclass1.h
// myclass.h
template< typename tClass1 >
class MyClass2
{
tClass1 * ptr;
void func( tClass1::e e );
};
// main.cpp
#include "enum.h"
#include "algo.h"
int main(){ return get_second<Enum>(); }
I don't think (I can be proven incorrect) that you can forward declare an internal type, nor an enumeration. You will need the definition of the enclosing class to use the enum.
While most style guides enforce not including unnecessary headers, in your case the header is necessary. Other options you can consider if you really want to avoid the inclusion would be defining the enumeration outside of the class and including the header that defines the enum.
Forward declaration of enumerations has actually been proposed by the C++ standards committee. See this paper (pdf). It would certainly be a good feature!
If you are really running into compilation slowdowns because of header inclusion, the other option is to use an int instead of an enum. This is a rather unpopular approach since it degrades type safety. If you do take this approach, then I would also recommend adding code to programmatically do the bounds checking:
// in class1.h
class Class1 {
public:
enum Blah {
kFirstBlah, // this is always first
eOne = kFirstBlah,
...
kLastBlah // this is always last
};
};
// in checks.h
#include <stdexcept>
namespace check {
template <typename T, typename U>
U bounds(U lower, T value, U upper) {
U castValue = static_cast<U>(value);
if (castValue < lower || castValue >= upper) {
throw std::domain_error("check::bounds");
}
return castValue;
}
} // end check namespace
// in class2.h
class Class2 {
public:
void func(int blah);
};
// in class2.cpp
#include "class2.h"
#include "class1.h"
#include "checks.h"
void Class2::func(int blah) {
Class1::Blah blah_;
blah_ = check::bounds(Class1::kFirstBlah, blah, Class1::kLastBlah);
}
It's not the prettiest solution, but it does solve the header dependency problem by moving some of the type safety that static compilation gives you into runtime code. I've use similar approaches in the past and found that a check namespace used in this way can make the resulting code almost as readable as enum based code with very little effort.
The caveat is that you do have to make an effort to write exception-safe code which I recommend regardless of whether you adopt this approach or not ;)