I never really had a necessity for a global variable in a template (and actually I don't support a design like this very much) but this topic got me curious.
Even though answered, it inspired me trying a different approach. Instead of using inheritance, I came up with this:
class Bar {};
class {
private:
Bar bar;
template <class T> friend class Foo;
} static foobar_singleton;
template <class T>
class Foo
{
public:
static Bar bar() { return foobar_singleton.bar; }
};
To me, the foobar_singleton works similarly to a 'non-member static private', since its content will be only acessible by the template class Foo. It also avoids inheritance though I am not sure this is an advantadge actually. My solution seems possible to be contained header-only, without necessity about another definition file.
I would like to see what are the opinions about this approach compared to the one utilized as an answer for the thread that got me curious. For instance, some examples of questions I'd like to hear about:
1. Do you see any clear advantadge in my example? Or for that matter, clear disavantadge?
2. Would you advice making bar attribute a static member and naming the class used as singleton?
3. This reminds any of you of any design pattern? Similar to pimpl idiom maybe?
4. You see any compiler portability problems? (I've tested it only with MSVC and GCC)
5. I'm right about being a possible header-only implementation? I'm actually not completely sure about the static variable foobar_singleton
Thanks in advance!
The static variable foobar_singleton in your example will be a different variable in every translation unit (internal linkage!). Which is a kind-of a show stopper.
The inheritance in the original topic is only used to "inject" the common static variable into the namespace of the template. If that's not a requirement, just don't derive Foo from FooBase, works just as well.
If it's needed for whatever reason, I would derive privately, which should eliminate any possible side effects one could encounter from introducing an additional base-class. And of course add the helper-class as the last base-class, if Foo inherits other classes too.
If you want a header-only solution:
typedef int Bar;
template <class DummyType>
class FooCommonStatics
{
static Bar s_bar;
template <class T>
friend class Foo;
};
template <class DummyType>
Bar FooCommonStatics<DummyType>::s_bar;
template <class T>
class Foo
{
public:
// void is just a dummy-type, any type that's not dependent on T would do
typedef FooCommonStatics<void> CommonStatics;
Foo()
{
CommonStatics::s_bar++;
}
private:
T m_something;
};
Related
I'd like to define two variations of a class depending on a template parameter in a C++ class. (I'm using C++17.)
For example, if the template parameter bool flag is true, I'd like the class to have a member:
Class1 foo;
and if flag if false
Class2 bar;
The class definition would also have some logic variation and use either foo or bar. I could implement this using inheritance but I'm exploring if there's another approach. It seems that https://en.cppreference.com/w/cpp/types/conditional may be helpful but I'm not sure. I could also just have both members and just use one of them in any given object, but that seems wasteful and there must be a better way. Note that I don't necessarily need to name the members differently if a particular solution would simply allow me to swap out the class but not the name (perhaps with conditional?).
If you can live with the same member name for both versions, then it is trivial:
template <bool flag>
struct Foo {
std::conditional_t<flag, Class1, Class2> foo;
};
Is there any interest to forward a class as a struct and vice versa ?
It seems to be perfectly legal, but some use cases exist ?
struct Bar;
class Foo
{
Bar * bar_;
};
class Bar
{
};
There isn't a use case any more or less than there is a use case for forward declaring with the same keyword. It makes no difference to the meaning of the program. The class-key identifier only makes a difference when defining the class.
The above applies to standard compliant compilers. Some non compliant ones might handle the declarations differently in which case there is a case for using the same keyword in particular.
Ok, here is a practical use case. Let's say you've implemented a class with the struct keyword. Over time, the class is widely used across multiple code bases and it is declared in many headers using the same keyword. At a later time, perhaps after adding a ton of features, you decide that classwould be more appropriate and you refactor the code. Now, there isn't a point in refactoring all the unrelated depending code bases to use the new keyword.
struct Bar;
class Bar;
These are equivalent, it doesn't matter.
but some use cases exist ?
No special ones IIRC.
From the language's point of view, there is no difference between forward-declaring a class as struct or class.
class Foo;
struct Foo;
class Bar;
struct Bar;
class Foo{}; // 100% ok
struct Bar{}; // 100% ok
Unfortunately, some compilers mangle those keywords differently. As described here, this can be nasty when you're depending on name mangling being the same.
Consider:
// process.h
struct Foo;
void processIfNotNull(Foo*);
// foo.h
class Foo{};
If you export such function in your shared library, your users will not be able to call processIfNotNull unless they have the definition of Foo.
It's not usefull.
In C++ the difference between struct and class is that for struct members are public by default.
Considering this, in your example it could just confuse the code reader to determine if your class will behavior as a struct or a class.
You can read this post for further information : When should you use a class vs a struct in C++?
The following code doesn't compile because the compiler doesn't know what foo::bar is when it encounters it.
class foo : foo::bar {
class bar {
}
}
Is there any way to make this code (or some variation of it) compile?
If the inheritance from bar is an implementation detail and the goal is to avoid polluting the global namespace (or the library's namespace), a common approach is to put these implementation details in a namespace named detail. This is a convention used in libraries like Boost, for example.
namespace super_cool_library {
namespace detail {
class bar { };
}
class foo : detail::bar {
};
}
The detail namespace is, admittedly, just a convention, but most people understand that within said namespace there be dragons.
Edits:
As Emilio Garavaglia suggests, foo would need to befriend detail::bar if detail::bar should need to have the same access to foo that a C++11 inner class would have.
I don't know why, but I find this question very interesting. Especially seeing how many answer try not to give a technical reason why the language don't allow this, but try to convince the author about the "ugliness" of such a definition (tha's ultimately a subjective matter).
Although the form of the question looks unconventional, what is asking is perfectly linear: since recursion is one of the primitives behind certain programming paradigms (that C++ claim to support, like the functional paradigm), if functions are allowed to be recursive (either directly or indirectly) why the same cannot apply to data definitions?
After all, if what is asked is possible a universe of interesting features opens in the area of meta-programming: when a generic traits class is used as a type generator for a generic class defining generic algorithms on top of a generic state, having a constructor like that can allow (among other things) to place the type generator into the generic class itself, simplifying the overall parametrization, leading to a completly different way to approach the generic algorithms and their "progressive partial specialization".
The rereason why this is not possible, is that C++ compilers, have to support independent translation units (that links after compilation), and have to support a non-orthogonal grammar (this is know as the "undecidable syntax problem").
Because of those two facts together, C++ cannot have a pure recursive global parser. You cannot use "unknown symbols" letting the association of that symbol to something concrete to happen later because the way to interpret the expression that symbol appears in, depends on the nature of that symbol itself: a<b>c is declaration of a variable, or an expression involving variables? You cannot know if you don't know if a and b are variables or types.
And since the "nature of a symbol" is "compiler internal state", you cannot use foo::bar as it is a class (like as a base to form a derived one) before knowing it really IS a class (and not a variable or something else). But this happens only later (when the class bar declaration is met).
This is the same reason that lead to have forward declarations, and declaration separated from definitions: a(b) cannot be transalted if at least a is not known to be a "callable object". If a is function, at least its prototype must be known when a(b) is met.
But in your case there is no way to anticipate the foo::bar declaration being the bar declaration to stay inside the foo definition.
To come to a solution the language should support someting like
1: class foo; //we know foo is a class
2: class foo::bar; // we know bar is a class inside foo scope
3: class foo::bar
{
...
}; //we know here how wide foo::bar is
4: class foo: public foo::bar // we must know about foo::bar width here...
{
...
}; //... to sum up the foo size.
The problem, here, is that 2: is not legal C++: the compiler has not yet seen the bar symbol alone, with the word class before it.
But this requires
class foo
{
class bar;
};
to already exist. But if you make that to exist you cannot anymore declare class foo: public bar {...}; later.
In other words, you meet an non-orthogonality in the grammar. The point is that it will not be solved, since around this inconsistency there have been deployed a number of programming paradigms that does not require that construct to work, and have already make enough brainwashing to let sooo many people (just look at the comments in you question and under the most of the answers) the let them to just refuse the idea even before trying to understand if it can be useful to something. They just say "I don't like that something, since I just have something else to like, and that can disturb me. And try to find false metaphors to support motivations that -ultimately- reside in the old C compilation model C++ still has to deal with.
It's not possible to have the outer class inherit from a nested class. It also doesn't make that much sense if you think about it. A class derives from its internal subclass? That's like a snake eating its own tail.
More likely you want both to share common methods. In this case you can create another class which provides a common interface/base for foo and foo::bar.
class common_base{ /* ... "shared" content ... */ };
class foo : public common_base{
class bar : public common_base {
/* depending on what you want to do this can be empty */
}
}
you can however do this:
struct A
{
struct B
{
};
};
struct C : public A::B
{
};
I don't think C++ supports what you want, but if the goal is to avoid polluting the global namespace with "bar", how about putting bar into a separate namespace? E.g.
namespace shums_private_namespace {
class bar {
};
};
class foo : shums_private_namespace::bar {
public:
foo() {/* empty */}
};
I have no idea why you'd want to do this, but if it's tricks you're looking for, CRTP-like things are always fun:
template <typename T>
struct Foo : public T
{
struct Bar
{
};
};
struct empty {};
int main()
{
typedef Foo<empty>::Bar Bar;
Foo<Bar> f;
}
I want to declare a friend class only if some (compile-time) condition is true. For example:
// pseudo-C++
class Foo {
if(some_compile_time_condition) {
friend class Bar;
}
};
I did not find any solution on the internet. I went through all the answers to the question Generating Structures dynamically at compile time. Many of them use the C++11 std::conditional, but I would like to know if it is possible to do this in C++03 without using the preprocessor.
This solution https://stackoverflow.com/a/11376710/252576 will not work because friendship is not inherited ( friend class with inheritance ).
Edit Just to make this more easily visible, as mentioned below in the comment: This requirement is unusual. This is part of a new research project in hardware simulation, that I am working on. The testbench is written in C++, and I want to display the variables in a waveform. I have researched various other options, and figured out that I need to use a friend class, due to practical considerations. The friend will capture the values and generate the waveform, but I would prefer to have the friend only when the waveform is required, and not all the time.
Use friend std::conditional<C, friendclass, void>::type; where C is your condition. A nonclass type friend will be ignored.
The conditional template is easily implemented in C++03. However since C++03 does not support typedef friends you need to use the following syntax there
namespace detail { class friendclass {}; }
class Foo {
friend class std::conditional<C,
friendclass, detail::friendclass>::type::friendclass;
};
Note that the detail dummy class name needs to match the name of the potential friend in this workaround.
[class.friend]/3 tells this :
A friend declaration that does not declare a function shall have one of the following forms:
friend elaborated-type-specifier ;
friend simple-type-specifier ;
friend typename-specifier ;
therefore it is not possible to conditionally declare friends of a class, without a macro.
It seems, unfortunately, not possible within the C++ compiler: ie, it seems that only the preprocessor may help here. Note: Johannes has a proposal, so there is hope!
However I would note that:
friendship does not require you to actually use it
friendship is a pure compile-time construct (like access specifiers) and does not incur any runtime penalty on any major compiler
there is no reason not to have unconditional friendship, but only use it if some conditions (static or dynamic) are met.
Note: in the future, this is something that the static_if proposal could cover.
Note: Johannes has pretty much nailed it. In '03 you cannot befriend
a typedef - but if you know you have a class, then you can refer to
it's injected class name.
Johannes' answer also has the benefit of using standard library functionality which too is always a good thing.
#define some_compile_time_condition 0
class Foo;
template <int Condition> class TestCondition {
private:
friend class Foo;
struct Type {
struct Bar;
};
};
template <> class TestCondition<1> {
public:
typedef Bar Type;
};
struct Bar
{
public:
void foo (Foo &);
};
class Foo {
private:
friend struct TestCondition< some_compile_time_condition >::Type::Bar;
int m_i;
};
void Bar::foo (Foo & foo)
{
foo.m_i = 0;
}
It's still different to the requirement in that Foo always has a
friend, but the befriended class changes based on the value of the
option.
An interesting side question is whether it is an ODR violation to have
versions of Foo both with and without some_compile_time_condition
set to 1.
I think you take 1 preprocessor and write your source code inside that.
bool flag = false;
#ifdef _MY_FRIEND_
friend class sample
flag = true;
#endif
if (flag)
{
...
...
...
}
class Foo {
#ifdef _MY_FRIEND_
friend class Bar;
#endif
}
};
Here _MY_FRIEND_ is a preprocessor and if you add that preprocessor then at compile time your class Bar will be the friend class...you can use that preprocssor any where when you want to need class Bar as a friend class.other wise compile without the preprocessor then it wont allow u to add Bar as a friend class of Foo
Please correct me if i understood the question wrong.
Is this answer considered "good" code or is it just an ugly hack?
And I would like to know how this is forward-declared (both classes).
When I just forward-declare the class with 2 template-parameters, it just always takes this one, no matter what value flag has.
I would like to do this because I have 2 special member functions which should behave differently on flag being true and I don't feel like reimplementing the whole class. Also, it should have the same name. According to this example, this seems to be possible.
And I have to forward-declare it because I'm creating a library in which we forward-declare everything.
Any idea?
It has the drawback that it doesn't really work. The base member function is not overridden, but it is just hidden by the derived class' function when you try to call it from outside. Which means if you call doSomething out of the base class (where presumably all your other functions live) it will call the base class doSomething which is not what is wanted.
The accepted answer on that question shows multiple ways for how you can solve your problem.
In order to use specialisation its definition always has to be visible to the caller. If, for example, you have template <class Type, bool flag> struct something defined in one header and template <class Type> struct something<Type, true> : public something<Type, false> defined in the second one, to use the latter you have to include the second header. Without that you will always get the first, more generic type.
EDIT: the bit about forward-declaring got me thinking. If you want to use only type declaration, as in pointer variable, do the following:
Header
template <class Type, bool flag>
struct something;
struct Test
{
something<int, true>* ptr; // definition not needed
Test();
}
Source
#include "something.h" // header with template
#include "something_spec.h" // header with specialisation
Test::Test()
{
ptr = new something<int, true>(); // specialisation used
}