I was wondering if it would be possible to do the following:
template <typename T>
namespace basic_foo {
struct str {
T value;
};
}
basic_foo<char>::str s1;
namespace foo = basic_foo<char>;
foo::str s2;
Is it possible to do this in any c++ compiler?
Is there work being done to implement this?
I think that it would be a great addition to the language.
Thanks in advance.
No, you cannot define a namespace template. You can, however, achieve almost exactly what you want (with only slightly different syntax), by making basic_foo a class template:
template <typename T>
struct basic_foo {
struct str {
T value;
};
};
basic_foo<char>::str s1;
typedef basic_foo<char> foo;
foo::str s2;
No, but you can use templated struct:
template<typename T>
struct basic_foo
{
struct str
{
T value;
};
};
typedef basic_foo<char> foo;
foo::str s1;
You could also use class instead of struct, but you would have to remember about public: in such case.
No. It`s impossible, namespace template is unreal, but you can make class template.
The other answers explain how to do what it looks like you might want. But it sounds like you have a different idea of what a namespace is for than what it really is designed for.
namespace solves the problem of two unrelated C++ code bases being able to communicate with each other. C doesn't have namespaces and is much more verbose as a result. Try using a 3rd party library such as openssl or oauth in C. You'll find a lot of function calls like this:
openssl_create
openssl_connect
and so on. And this is really, really important. Because chances are I want to write a function called connect. And so does the author of the ZMQ library I used. And so forth. And it's a major, major pain to have two functions with the same name trying to be called in the same place...
namespace is purely a software engineering construct, not a programming one. It lets the prefix openssl_ simply become the namespace so code like the above can intermingle more freely. Why don't namespaces conflict? This is where software engineering becomes even more human and social, as essentially the global programming community must make sure this doesn't happen. Generally outer namespaces are usually companies; I would guess all Google internal code is in namespace Google. Java solves this by promoting the convention of naming package (like namespace) by the internet domain name, which is presumably a real-world entity that can't conflict, e.g. Google code should live in package com.google...
I should also note that within an organization namespaces are used at the application, or product, or team level - e.g. Google Drive probably has a function "upload" somewhere as does Google Mail, and those teams might generally not talk to each other... but still need to write intermingling code.
That's what namespaces do. Nothing more, nothing less.
Related
So normally I wouldn't ask a question like this because it seems like it could be opinion based or start some sort of verbal war on coding practices, but I think there might be a technical reason here that I don't understand.
I was looking over the code in the header files for vcpkg (a library packing manager that Microsoft is creating and is "new" code) because reading code generally is a good way to learn things you didn't know.
The first thing I noticed was the use of using rather than typedef.
Snippet from 'https://github.com/microsoft/vcpkg/blob/master/toolsrc/include/vcpkg/parse.h'
template<class P>
using ParseExpected = ExpectedT<std::unique_ptr<P>, std::unique_ptr<ParseControlErrorInfo>>;
I haven't personally used using this way before and an answer from: What is the difference between 'typedef' and 'using' in C++11?. Essentially, using is the new way to do it, and the benefit is that it can use templates. So Microsoft had a good reason to use using instead of typedef.
Looking at 'https://github.com/microsoft/vcpkg/blob/master/toolsrc/include/vcpkg/commands.h' I noticed that they did not use any classes. Instead it was only namespaces with a function or so in them. ie:
namespace vcpkg::Commands
{
namespace BuildExternal
{
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet);
}
}
I'm guessing that part of this is that the calling syntax looks essentially just like a static member function in a class, so the code performs the same but maybe saves some overhead by being a namespace instead of a class. (If anyone has any ideas on this too that would be great.)
Now the main point of all this. Why is Microsoft using structs instead of classes in their namespaces?
Snippet from 'https://github.com/microsoft/vcpkg/blob/master/toolsrc/include/vcpkg/parse.h':
namespace vcpkg::Parse
{
/* ... Code I'm excluding for brevity ... */
struct ParagraphParser
{
ParagraphParser(RawParagraph&& fields) : fields(std::move(fields)) {}
void required_field(const std::string& fieldname, std::string& out);
std::string optional_field(const std::string& fieldname) const;
std::unique_ptr<ParseControlErrorInfo> error_info(const std::string& name) const;
private:
RawParagraph&& fields;
std::vector<std::string> missing_fields;
};
}
Searching stackoverflow, I found an old question: Why Microsoft uses a struct for directX library instead of a class?
Which the answers were essentially, you don't have to declare things as public as default and a comment way at the bottom saying that it was old code.
If vcpkg was old code I would be completely satisfied, however, this is new code. Is it just some style they have that is a carry over (but using vs typedef isn't)? Or is it to save a line of code (public:)? Or is there some sort of overhead benefit? Or some other thing I haven't considered at all?
The only differences between struct and class are:
the default member access (public vs private) and
the default inheritance if you inherit from the type (public inheritance vs private inheritance).
The end result of 1 will be the same once the author has finished adding public:/private: to the type. 2 you can easily control yourself by being explicit when you inherit, rather than rely on the default. It's hardly a big deal and doesn't really matter.
As to why Microsoft uses struct rather than class in their code, you will have to ask some Microsoft people.
Regarding the free functions vs static functions, I don't think there is any overhead in this with classes (I haven't measured this at all, I would just think that most compiler would recognize that the class is basically just a namespace for the function). The thing is just: You don't need a class.
Using a class with only static functions is basically abusing the class as a namespace. So if you are only doing that, then be explicit about it and just use a namespace. Having a class there would only be confusing since you would think that maybe there could be some state here and just see that there is non when you see that the function in the class is static.
This is especially relevant if this is used a bit wrongly. Imagine someone instantiates a class A a with static member function f to call a.f(). It is no problem regarding performance, since the construction is a no-op and it will pretty much be equivalent to A::f(). But for the reader it seems like there is some kind of state involved and that is just confusing.
Regarding the other two: using is just superior to typedef throught being able to use templates and is (IMO) better readable. The struct vs class issue is just something over what has the better defaults, its not a big difference, but most often, what you want is what a struct does, so there is no reason to use a class.
To be (more) compatible with C
To avoid making everything public by using the public: keyword, since that all COM objects for example have only public member functions.
I am refactoring a widely used class. Given how widely it is used, my intend is to create a version 2 of the class. I will keeping the interfaces same/similar [I am forced to make some changes, otherwise it will become ugly with new changes] so that switching from old class to new class becomes easy. And we can switch applications using the old class to new class one by one.
Now I am not sure how to manage name / namespace in this case.
Eg:
Currently, lets say, the class is under a namespace 'app'
namespace app {
class Important {
...
};
}
I would like to keep the class name same or very similar so that the meaning is clear.
namespace app {
// This looks okay (conveys the meaning), but is ugly.
class Important2 {
...
};
}
namespace app {
namespace v2 {
// I think this will be confusing. It will given a feeling that the v2
// applies to app namespace. There are lot of classes under 'app'
// namespace which are not changed.
class Important {
};
}
};
Is there a better approach?
Thanks!
I think the best solution to your problem is to used the gof factory design pattern, where you have an interface and a number of implementations for example Important, Important2 etc.
You could then tell your consumer that you will be deprecating Important soon but a compiler warning
You could resolve via simple namespace alias.
A sample could be in this answer https://stackoverflow.com/a/41420638/781933, for a switch on/off approach (driving migrations on a per-project base).
If instead you have to go through intermediate compositions rather than a complete replacement you could adopt intermediate solutions with compositions and inline namespaces.
You can find a specific example of version management via namespacing in the Stroustrup's The C++ Programming Language.
In C++ its possible to do the following for namespace versioning
First version:
namespace A__v1 {
class X ...
class Y ...
class Z ...
}
namespace A = A__v1
Second version (where the X class is changed):
namespace A__v1 {
class X ...
class Y ...
class Z ...
}
namespace A__v2 {
class X ...
using A__v1::Y;
using A__v1::Z;
}
namespace A = A__v2
What i would like to know is, is it worth the effort? Does this really add any advantage to your application/library when changing the internals of a namespace?
I actually like the non-macro way of handling this, it allows one build of the library to serve many versions. This will inevitably increase library size (due to more versions of some classes all being present) but there is one caveat though: the compiler will most likely report the full namespace qualification of the classes, making the user of your library, who doesn't know about your non-standard versioning scheme very confused.
On second thought, I also don't see the use of supplying two versions of the same thing in one library build, except if there are different CPUs/architectures involved, but I don't think that's what you're getting at. Keeping old versions of classes around is not smart, people will never switch to the newer ones if they don't need to, and if something (half-internal) gets deprecated, you'll have removed something that was "part of the library" so to speak.
It's a nice trick and quite useful but there are some problems to be aware of. Mostly, you can't specialize a template using the name A for the namespace.
C++0X have inline namespaces which was designed to handle this better.
the library can be tricky for the programers who will use that namespace, maybe it's better to use separate namespaces independently to make the difference.
I want to expose a class from an external library to my library's users. Specifically I want to 'import' the class to my namespace so that the user does not need to know what libraries I am using behind the scenes. Often it seems that I can either do this by using a typedef, or by simply using the class. Is there any reason for choosing one method over the other (or doing something else)? (I seem to have some gaps in my education :) )
For example: I want to create a serial port manager that uses Boost::Asio.
namespace MySerialManager {
//should I use a typedef
typedef boost::asio::serial_port_base::flow_control flow_control ;
//or a using...
using boost::asio::serial_port_base::flow_control;
class SerialManager
{
//let the user specifify the flow on construction
SerialManager(const flow_control& fc);
}
}
or should I be doing something else altogether.... Many thanks.
Both have the same end result. using is maybe the more close to your intent.
If you wanted to "import" a class template, then using would be your only option. As it stands, I don't think there's any substantial difference. Personally, I'd go for typedef in the above case, because it's an older and more familiar construct.
I have a quick question regarding the use of typedefs for lengthy templates. The crux: I've found myself in something of a pickle—there doesn't seem to be a good place to place typedefs except local to client functions. While there are similar SO questions (see here for example), none seem to address this exactly. Please note that this question doesn't address whether typedefs are desirable in what follows—I've tried to simplify things for expository purposes.
My problem has arisen while working with boost::shared_ptr<T>. Basically, I want to do the following:
#include <boost/shared_ptr.hpp>
typedef boost::shared_ptr<Widget> WidgetPtr;
Placing this typedef in the Widget declaration header seems ugly. There seem to be two considerations here: (i) if Widget itself doesn't make use of shared pointers in its members, we've added an additional include (as we can't forward declare the boost::shared_ptr template class—correct me if I'm wrong?) (ii) if we want to make use of this typedef during the declaration of another class (call that class Foo) we violate best practices by including Widget.h instead of simply forward declaring Widget or including WidgetFwd.h... unless this typedef is duplicated in the latter. Furthermore, it doesn't seem make sense to typedef boost::shared_ptr<Widget> during the declaration of Widget itself—we seem to be mixing Widget's declaration with an anticipation of how clients will make use of the Widget interface.
Okay, so that's bad, but this is worse: if I don't attempt some combination of the above I end up with duplicate typedefs in client code, which yields inconsistency (and hence, likely, error)—the whole point being that given Widget, a WidgetPtr typedef should act as a type in its own right. Example: we don't want Foo to make use of one WidgetPtr, a typedef of boost::shared_ptr, while Bar is using WidgetPtr as a typedef for std::auto_ptr.
Another method (and one of the few that I've seen mentioned in online discussion) would be to make the typedef a public member of Widget and then use Widget::Ptr:
class Widget {
// ...
public:
typedef boost::shared_ptr<Widget> Ptr;
};
Again, I don't like this as (i) it suggests that the pointer type is somehow a member of the class and (ii) it leads to a wonky interface. Worse still: since every class that I write can potentially be pointed to using smart pointers, I end up chasing the imaginary client's tail. Ugly, ugly, ugly.
As it stands, I've removed the typedefs from this codebase (as they led to serious confusion, duplication) and re-introduced them locally in selected functions. Here again there's a problem with inconsistent usage but it's not quite as severe.
The only other solution I can think of—and again I'm not sure whether this is considered good practice—would be to have a utilities header in which the typedefs are placed, potentially within their own namespace. In this header we'd include and be done with it.
Am I missing something obvious or is this just plain tricky?
PS—Apologies for the length of the above; I couldn't find a simpler way of fully expressing the problem.
Furthermore, it doesn't seem make sense to typedef boost::shared_ptr during the declaration of Widget itself—we seem to be mixing Widget's declaration with an anticipation of how clients will make use of the Widget interface.
First of all, this is not at all wrong - after all, the means of how the clients will (and can) use the interface is part of the interface itself; and for C++, not being garbage-collected, memory management of objects is a rather crucial part of their interface.
So there are two cases. In one case, the Widget would anticipate it would be used through a shared pointer. This would mean that eg. child widgets obtained from a widget are returned as shared_ptrs, everywidget created has it shared_ptr and so on. It would be totally legitimate to typedef WidgetPtr in the same header as Widget.
In the second case, Widgets would expect to be managed eg. by ordinary new and delete. The clients can use shared_ptrs in special cases, but nothing says eg. a printer dialogue routine can't use auto_ptr instead. The clients have to be prepared that if wptr is a shared_ptr, the line
shared_ptr<Widget> w2(wptr->firstChild()->parent());
leads to a disaster.
Your question seems to indicate the latter is your case. So IMHO, what you've done is OK. The clients can choose their means of managing Widget objects, as long as it doesn't affect other clients.
I don't like a library dictating the use of a particular smart pointer, but I tolerate it if it is necessary.
If you wish to force users to always use a shared_ptr to manipulate a widget, it's impossible, so don't even bother trying.
On the other hand, if you have a method from Widget which returns a boost::shared_ptr<Widget>, then providing a (sane) typedef might simplify the client code.
I would therefore promote the use of an inner typedef:
class Widget
{
public:
typedef boost::shared_ptr<Widget> Ptr;
Ptr AccessFirstChild();
}; // class Widget
in which case it's perfectly okay to #include the necessary headers.
You are overthinking this in my opinion. Everybody who wants to have a shared_ptr<Widget> is going to have to include the Widget header file anyway. Putting the typedef (which is a good idea imo) in Widget.h makes 100% sense to me.
My approach (using underbar types, just because it is how I do it)
class Type
{
public:
typedef shared_ptr<Type> ptr;
typedef shared_ptr<const Type> const_ptr;
};
I have found the const_ptr version is pretty darn useful.
I used to structure my C++ code into libraries. A library would have a bunch of headers for client consumption, all inside the include/LibraryName directory. Also, I would have one header called Fwd.h inside this directory with forward declarations of all classes along with their pointer typedefs.
In addition, each public header would include Fwd.h so that including the header would automatically give you all forward declarations and pointer typedefs. This worked really well in practice.
Not all classes are necessary to place in a shared_ptr though. I would only create pointer typedefs for types that I expected to be created dynamically, and in this case I would supply a factory. This has the added benefit that you may get away with supplying client code with interface types only, and hide concreted implementations in your library's src directory. Not specifically what you asked advice for, but this gives the complete picture of my method. As a final point, it's also possible to supply a convenience header called LibraryName.h that includes the Fwd.h and all other public headers.
Good luck!
I generally use this approach to ease typing and makes a generic shared pointer interface for classes.
Do note it's C++0x.
#include <iostream>
#include <memory>
template <class T>
struct SharedVirtual
{
typedef std::shared_ptr<T> VPtr;
};
template <class T>
struct Shared
{
typedef std::shared_ptr<T> Ptr;
template <class... P>
static Ptr ptr(P&&... args)
{
return std::make_shared<T>(std::forward<P>(args)...);
}
};
class Foo : public SharedVirtual<Foo>
{
public:
virtual void foo() const = 0;
};
class Test : public Foo, public Shared<Test>
{
public:
void foo() const { std::cout << "Hai u!" << std::endl; }
};
void print(const Foo::VPtr& ptr)
{
ptr->foo();
}
int main()
{
auto ptr = Test::ptr();
print(ptr);
}
Second part first: use a namespace, i.e.:
namespace WidgetStuff {
class Widget { ..
typedef shared_ptr<Widget> WidgetPtr;
..
If you want to split it up:
namespace WidgetStuff {
class Widget { ...
}
...
namespace WidgetStuff {
typedef ...
You're the library author, you own the namespace, so no one else should invade it.
And now part one is answered too, if you choose you can do:
#include <widget.h>
#include <widget_utils.h>
by splitting up the namespace as above. The effect is no one has to use the utilities, whether or not they do they should not invade your namespace, so they're free to make WidgetPtr mean something else, as long as it isn't in your namespace.