And which templating library should new beginner user?
Not sure if OS matter,I'm talking about windows if that matters.
Templates are all about generic programming. The concept is like: you define a function body/class that will work with any kind of data (having some properties, like a specific operator defined). Consider you are writing a function that will return summation of its given parameters:
int sum(int a, int b)
{
return a + b;
}
Now you want that the function should work for strings as well. But you can't do the following:
std::string s1 = "abc", s2 = "def";
std::string s = sum(s1, s2);
For this sum() calling you need to define another version of sum(). Templates will save your work. Just write the definition of sum() in following way:
template<typename T>
T sum(const T& a, const T& b)
{
return a + b;
}
Now the function sum() will work for any data type for which operator+ is defined.
EDIT
You need to learn STL (Standard Template Library) first, if you want to be a C++ programmer.
For beginner it is better to start from a good book. And the Standard Library (often also called STL) is the template library you should start from.
Templates are a feature of the core C++ language, and implemented by all C++ compilers. You can write a template without using any library. That just means that you have to provide all of the template code; the compiler will turn that code into the appropriate assembly as needed.
The core idea behing templates is the notion of generic code. The code you need to for a linked list of integers looks almsot the same as the code for a linked list of strings; for an array of integers almost the same as an array of strings. Templates allow you to write a linked list of T objects, wihout specifying T up front. Then, when you need a linked list of integers, you just tell the compiler to instantiate that linked list with T==int.
Now, linked lists are quite common. You therefore don't have to write the linked list template; the Standard Library (included with every compiler) contains the std::list<T> template. To use it, just tell the compiler what kind of list you need. std::list<float>, std::list<std::string>, etcetera. In addition to such container classes, there are also algorithms. Those too are templates - std::sort< > can sort many different containers. Unlike qsort from C, the C++ compiler knows what it is sorting, and that makes std::sort< > faster.
The ATL is a microsoft library. It uses templates for the same reason as the Standard Library - not as a goal in itself, but because it allowed Microsoft to write code that you can then tailor for your particular need. For instance, there are thousands of COM interfaces. The ATL doesn't need to provide different code for each and every COM interface; instead it provides a few templates that are instantaited for every COM interafce you want to use.
principle? I'd have to say it boils down mostly to not 're-inventing the wheel' and rapid application development(RAD), by creating generic code that can be reused in differect situations just by chnaging the template parameters. a good example of this is std::list or std::vector
As for what to use, well that depends on your goals(ie: what sort or pragram are you making, what will it need to do?), generally though you can use either boost and/or the STL libraries that ship with most compilers these days
Related
I want to call a C++ dynamic library (*.so) from Rust, but I don't want to build it from Rust. Like this,
cc::Build::new()
.file("src/foo.cc")
.shared_flag(true)
.compile("libfoo.so");
In some cases, I only need to call several functions, not all the functions. How can I use it?
Before you go further, make sure you have a basic idea of Rust FFI (foreign function interface).
In Rust, it's easy to call C, but hard to call C++.
To call C functions in Rust, you just have to wrap them with extern, do some basic type casting and sometimes unsafe.
To call C++ functions, since Rust does not have built-in knowledge of C++ features, you may have to do a lot of manual translation. For example, here is part of the documentation from Rust-Qt:
Many things are directly translated from C++ to Rust:
Primitive types are mapped to Rust's primitive types (like bool) and types provided by libc crate (like libc::c_int).
Fixed-size numeric types (e.g int8_t or qint8) are mapped to Rust's fixed size types (e.g. i8).
Pointers, references and values are mapped to Rust's respective types.
C++ namespaces are mapped to Rust submodules.
C++ classes and structs are mapped to Rust structs. This also applies to all instantiations of template classes encountered in the
library's API, including template classes of dependencies.
Free functions are mapped to free functions.
Class methods are mapped to structs' implementations.
Destructors are mapped to Drop and CppDeletable implementations.
Function pointer types are mapped to Rust's equivalent representation. Function pointers with references or class values are
not supported.
static_cast and dynamic_cast are available in Rust through corresponding traits.
Names of Rust identifiers are modified according to Rust's naming
conventions.
When direct translation is not possible:
Contents of each include file of the C++ library are placed into a separate submodule.
Method overloading is emulated with wrapping arguments in a tuple and creating a trait describing tuples acceptable by each method.
Methods with default arguments are treated in the same way.
Single inheritance is translated to Deref and DerefMut implementation, allowing to call base class methods on derived
objects. When deref coercions are not enough, static_cast should be
used to convert from derived to base class.
Getter and setter methods are created for each public class field.
Not implemented yet but planned:
Translate C++ typedefs to Rust type aliases.
Implement operator traits for structs based on C++ operator methods (issue). Operators
are currently exposed as regular functions with op_ prefix.
Implement Debug and Display traits for structs if applicable methods exist on C++ side.
Implement iterator traits for collections.
Subclassing API (issue).
Provide access to a class's public variables (issue).
Provide conversion from enums to int and back (used in Qt API).
Support C++ types nested into template types, like Class1<T>::Class2.
Not planned to support:
Advanced template usage, like types with integer template arguments.
Template partial specializations.
Template methods and functions.
My suggestion is to wrap your C++ library as a C library, then call it the official FFI way, or use rust-bindgen to automatically do the wrapping.
If you still want to call C++ in Rust, rustcxx seems like a handy tool.
As to the library linking, it's pretty simple:
Put the library into your system library searching paths like /usr/lib or /usr/local/lib/, make sure it can be found by ldconfig -p.
Or use the environment variable LD_LIBRARY_PATH to specify the path where your library lays when you run cargo from the CLI.
According to Rust's official website, there is no official support for linkage with C++. Instead you can try and use C libraries.
There is also a thread on this issue in their users forum, where users suggest some 3rd party projects aiming to tackle this issue:
bindgen - Auto generation of FFI for Rust
cpp-to-rust - Allows to use C++ libraries from Rust. The main target of this project is Qt.
I didn't use them, so I can't recommend anything particular or share my experience, but good luck :)
I feel it's worth mentioning as of now there is CXX library in crate
https://docs.rs/cxx/latest/cxx/
https://cxx.rs/
This is what I will be using going forward in order to interoperate with a C++ Library from a vendor.
The assigned answer has a link but it's publicly archived and all active work is likely here :
https://github.com/dtolnay/cxx
Go vs C++ interoperability has been discussed many times so far (here, for example), and generally it has been shown that it's possible to wrap C++ functions in C functions, and than to wrap C functions in CGO functions. This is the way how to use C++ code in Go application. However, the most of examples consider only functions with parameters of primitive data types (like int or char *).
But what if C++ function expects STL containers like std::vector or std::set to be passed? There are no equivalents for them in C, so I have no idea what to pass from C to C++.
static Status GetApproximateMemoryUsageByType(
const std::vector<DB*>& dbs,
const std::unordered_set<const Cache*> cache_set,
std::map<MemoryUtil::UsageType, uint64_t>* usage_by_type);
UPD
Just for the reference, here is the example of how this problem was solved. This is a real function from RocksDB C++ API. In order to use it in Go, it should be wrapped in function (or several functions) that are written in C++, but look like as just they're written in plain C. These wrappers are compiled to library with Go binary links against.
I want to know whether it is possible to do generic programming in C++ without using templates. Is it possible to write all libraries available in C++ which are written using templates without using templates. Is there any alternative available in C++ for templates?
I want to know Is it possible to write an abstraction over libraries written in C++ using templates which provide me with the same functionality
Theoretically, C++ without templates is still Turing-complete, so you can write a program for every function in that language that can also be written in C++ with templates. To my knowledge, the macro preprocessor in C++ is not Turing-complete, but templates are. So there must exist functions which can be implemented purely as templates, but not with macros.
Practically, I don't think it is possible to re-implement everything with the same semantics. Without templates, you probably will have to sacrifice type-safety and stick to using macros, void* or inheritance-based approaches like the early Java classes did even for simple container libraries.
For more advanced meta-programming libraries, e.g. expression templates, dimensional analysis frameworks, Boost.Spirit Boost.Proto, I doubt that they can be implemented without another form of meta-programming. Macros may work, but this will be more like a code-generator and defer type-checking to the compiler and error messages will be even worse than what we have right now with templates. In addition, the semantics are different w.r.t parameter passing.
Well, templates are just that — templates. They are blueprints for actual types and functions. So, theoretically, you can make all of those template instantiations by hand. But that wouldn't be generic programming any more.
Answer for question:
Is there any alternative available in C++ for templates?
Macroses is alternative of templates. (Not good alternative, but alternative)
Related links [1],[2]
Compare:
#define min(i, j) (((i) < (j)) ? (i) : (j))
template<class T> T min (T i, T j) { return ((i < j) ? i : j) }
Problems of macroses:
no type checking,
not so understandable compiler errors becouse macroses expanding
sideffects of multiple computing expressions
About question:
Is it possible to write all libraries available in C++ which are written using templates without using templates.
It is possible to use macroses in some cases. It is possible to write or generate implementation for each library type. But for user defined type library can not have implementation, except simple cases when macroses may be useful.
Earlier pure C (not C++) programs have contain special tools in sources that was used at build stage to generate some sources from some "presource" templates.
This question already has answers here:
How does the compilation of templates work?
(7 answers)
Closed last year.
As some of you may know from my recent posts i am studying for a C++ exam which the content for the class was delivered very poorly. I am basically having to self teach everything myself so bear with me here.
This is an exam question:
(i)Explain the concepts of templates as defined in the C++ language.
Be sure to differentiate between what the programmer does and what the
compiler does.
My current rationale:
(i) A template allows a function or class to operate using generics. This allows the programmer to effective program X functionality once, and be able to use this functionality with many different data types without having to rewrite the application or parts of the application multiple times.
My problem is i have no idea how the compiler handles the use of templates.
I am unsure what the compiler does at this stage, if somebody could clear this up it would be helpful.
Templates in C++ are implemented through substitution. It's not like Java generics which just type check the code which involves the generics class and then compiles it using raw references (type erasure).
Basically C++ creates a different class/method for each actual template argument used in your code. If you have your
template<typename T>
void myMethod(T t)
{
//
}
what happens at compile time is that a different method is compiled for each type the template is actually used. If you use it on myMethod(50) and myMethod("foo") then two overloaded version of the method will be available at runtime. Intuitively this means that templates could generate code bloating but in practice the same expressiveness is obtained by a larger codebase without templates with less readability so that's not a real concern.
So there is no black magic behind them (ok there is if you consider meta programming or partial specialization).
let's say you write a function using templates:
template <typename T>
void function(T t){
doSomething();
}
for each data type you call this function, the compiler simply replaces the 'T' with that data type, say 'int' and generates code for that like you've written this function with 'int' instead of 'T' since the beginning.
This is probably the right (but not the complete) answer if others agreed.
For each instance of an object of a different type that you create or in case of functions the different type of arguments that you use, the compiler simply makes an overloaded version at compile time. So if you have a template function like a sort function and use that function for int and double arrays, then the compiler have actually made two functions: one using int and the other using double. This is the simplest explanation I could give. Hope it's useful.
When designing a C++ library, I read it is bad practice to include standard library containers like std::vector in the public interface (see e.g. Implications of using std::vector in a dll exported function).
What if I want to expose a function that takes or returns a list of objects? I could use a simple array, but then I would have to add a count parameter, which makes the interface more cumbersome and less safe. Also it wouldn't help much if I wanted to use a map, for example. I guess libraries like Qt define their own containers which are safe to export, but I'd rather not add Qt as a dependency, and I don't want to roll my own containers.
What's the best practice to deal with containers in the library interface? Is there maybe a tiny container implementation (preferably just one or two files I can drop in, with a permissive license) that I can use as "glue"? Or is there even a way to make std::vector etc. safe across .DLL/.so boundaries and with different compilers?
You can implement a template function. This has two advantages:
It lets your users decide what sorts of containers they want to use with your interface.
It frees you from having to worry about ABI compatibility, because there is no code in your library, it will be instantiated when the user invokes the function.
For example, put this in your header file:
template <typename Iterator>
void foo(Iterator begin, Iterator end)
{
for (Iterator it = begin; it != end; ++it)
bar(*it); // a function in your library, whose ABI doesn't depend on any container
}
Then your users can invoke foo with any container type, even ones they invented that you don't know about.
One downside is that you'll need to expose the implementation code, at least for foo.
Edit: you also said you might want to return a container. Consider alternatives like a callback function, as in the gold old days in C:
typedef bool(*Callback)(int value, void* userData);
void getElements(Callback cb, void* userData) // implementation in .cpp file, not header
{
for (int value : internalContainer)
if (!cb(value, userData))
break;
}
That's a pretty old school "C" way, but it gives you a stable interface and is pretty usable by basically any caller (even actual C code with minor changes). The two quirks are the void* userData to let the user jam some context in there (say if they want to invoke a member function) and the bool return type to let the callback tell you to stop. You can make the callback a lot fancier with std::function or whatever, but that might defeat some of your other goals.
Actually this is not only true for STL containers but applies to pretty much any C++ type (in particular also all other standard library types).
Since the ABI is not standardized you can run into all kinds of trouble. Usually you have to provide separate binaries for each supported compiler version to make it work. The only way to get a truly portable DLL is to stick with a plain C interface. This usually leads to something like COM, since you have to ensure that all allocations and matching deallocations happen in the same module and that no details of the actual object layout are exposed to the user.
TL;DR There is no issue if you distribute either the source code or compiled binaries for the various supported sets of (ABI + Standard Library implementation).
In general, the latter is seen as cumbersome (with reasons), thus the guideline.
I trust hand-waving guidelines about as far as I can throw them... and I encourage you to do the same.
This guidelines originates from an issue with ABI compatibility: the ABI is a complex set of specifications that defines the exact interface of a compiled library. It is includes notably:
the memory layout of structures
the name mangling of functions
the calling conventions of functions
the handling of exception, runtime type information, ...
...
For more details, check for example the Itanium ABI. Contrary to C which has a very simple ABI, C++ has a much more complicated surface area... and therefore many different ABIs were created for it.
On top of ABI compatibility, there is also an issue with Standard Library Implementation. Most compilers come with their own implementation of the Standard Library, and these implementations are incompatible with each others (they do not, for example, represent a std::vector the same way, even though all implement the same interface and guarantees).
As a result, a compiled binary (executable or library) may only be mixed and matched with another compiled binary if both were compiled against the same ABI and with compatible versions of a Standard Library implementation.
Cheers: no issue if you distribute source code and let the client compile.
If you are using C++11, you can use cppcomponents. https://github.com/jbandela/cppcomponents
This will allow you to use among other things std::vector as a parameter or return value across Dll/or .so files created using different compilers or standard libraries. Take a look at my answer to a similar question for an example Passing reference to STL vector over dll boundary
Note for the example, you need to add a CPPCOMPONENTS_REGISTER(ImplementFiles) after the CPPCOMPONENTS_DEFINE_FACTORY() statement