What are the regex expressions for reliably finding C++ methods and classes?
There are no regular expressions to reliably find C++ methods and classes. You need a real parser.
Regular expressions really are not suited to parsing languages like C++. Features of the language like templates require additional knowledge to parse properly.
Consider the following
template<class T> T SomeTemplate();
typedef int SomeType;
if(SomeTemplate<SomeType>())
{
}
How do you distinguish between a comparison and calling a template function?
Related
So, I'm struggling to grasp the whole CRTP thing in C++. A few (1) (2) of the rationales I found online about why should you even care to use it is that it allows to add a functionality to your code in a semi automatic way. What I mean is that I can let the compiler deduce some functionality for me, asking me only for a few small implementation.
As an example, I may want to formalize a Comparable "trait" (using a Rust word), forcing the user to provide an implementation for < and ==, and deducing all other comparisons using just these two. IIRC, this is what happens when you instantiate a std::set of a custom class (the compiler asks you for a operator<() implementation).
So, I have two question about C++'s CRTP:
In this sense, is the usage of the word "trait" appropriate? And may I even go further and say abstract data type? Is CRTP the C++ idiom to achieve this (C++ purists, forgive me)? Because to me they seem very similar: you define some basic implementation, and following some deduction rules you can get other behavior/functionality
Can I get the same thing ("trait"-like thing) by using an abstract class? If so, why should I use a CRTP instead?
Thanks!
EDIT: in the comments I have been advised that in C++ the word "trait" refers to a particular concept, which is different to the one used for instance in Rust. So I slightly change/clarify my question: is CRTP similar to Rust's traits (IIUC, specifically the #[derive]d ones)?
The CRTP idiom is a tool that injects generic functionality into a class, specifically by inserting members into it. The general, language-neutral, term for this kind of thing is a "mixin." Mechanically, "mixin" usually refers to ways of injecting members into a class without using a base class. Since the CRTP uses base classes, it does not strictly fit the definition of a mixin. But this is a matter of mechanism, not concept; a CRTP base class fulfills the general function of a mixin even if not by the usual means.
Rust traits are kind of like mixins as well. But the CRTP is not like a Rust trait for one very important reason. The whole point of Rust traits is that the class on the receiving end does not have to know that they are being given a trait. In Rust, you can force a type to have a trait interface without that type having any idea that the trait even exists.
The CRTP can't do that. A class must choose to opt-into a CRTP-based mixin interface.
So no, I would not call the CRTP a Rust trait. Indeed, the C++ concept you found called "traits" are much more like Rust traits. C++ traits define an interface that any type could adopt, and via template specialization, a user can adapt its normal interface to the traits interface. Same idea, just via a different mechanism.
The nominal similarity is not a coincidence: the makers of Rust recognized the utility of the C++ traits idiom and built a language feature specifically to facilitate it (and thus dodging all of the cruft that comes from using traits-based interfaces in C++).
In addition to #Nicol Bolas excellent answer I would like to add some comments on #[derive] traits. In rust, you can automatically implement some traits for your structs using this keyword. Here is an example taken from the link above:
#[derive(PartialEq)]
struct Foo<T> {
a: i32,
b: T,
}
The equivalent in C++ would be an automatic mixin of code, such that Foo fufills the std::equality_comparable concept. This is currently impossible because an automatic implementation would require a built-in reflection system, which C++ does not have: We would have to inject an equality operator, that checks all data members for equality, so we need to know about all data members of the type we are injecting the functionality into. There is a current proposal for built-in reflection, but even with it, it would probably be impossible to write a CRTP base class PartialEq that implements a meaningful bool operator==(X const& other) const noexcept for you. Consider the following example:
// hypothetical crtp mixin
template <typename T>
struct Foo : public PartialEq<Foo<T>> {
int a;
T b;
};
PartialEq<Foo<T>> needs to know about all datamembers of Foo<T>, but at time of the definition of PartialEq, Foo<T> is incomplete: It must be defined afterwards, because it depends on PartialEq through inheritence.
But there is yet another proposal on facilitating metaprogramming in C++ that introduces features somewhat similar to procedural macros in rust. If it gets accepted and implemented, it will be added no earlier than 2026. This proposal includes something called a metaclass, which pretty much is very close to a #[derive] trait in rust - without CRTP. The syntax would look like this:
template <typename T>
struct Foo(PartialEq) {
int a;
T b;
};
This usage scenario is even explicitly mentioned in the proposal paper, though there is a talk of a regular interface (a supertrait, in rust-speak), that injects code to satisfy the equality_comparable concept together with some other code.
Sorry for the newbie question, but I have a feeling I am missing something here:
If I have a certain class template which looks like this (basically the only way to pass a lambda to a function in C++, unless I am mistaken):
template<typename V, typename F>
class Something
{
public:
int some_method(V val, F func) {
double intermediate = val.do_something();
return func(intermediate);
}
}
By reading the implementation of this class, I can see that the V class must implement double do_something(), and that F must be a function/functor with the signature int F(double).
However, in languages like Java or C#, the constraints for the generic parameters are explicitly stated in the generic class signature, so they are obvious without having to look at the source code, e.g.
class Something<V> where V : IDoesSomething // interface with the DoSomething() method
{
// func delegate signature is explicit
public int SomeMethod(V val, Func<double, int> func)
{
double intermediate = val.DoSomething();
return func(intermediate);
}
}
My question is: how do I know how to implement more complex input arguments in practice? Can this somehow be documented using code only, when writing a library with template classes in C++, or is the only way to parse the code manually and look for parameter usage?
(or third possibility, add methods to the class until the compiler stops failing)
C# and Java Generics have similar syntax and some common uses with C++ templates, but they are very different beasts.
Here is a good overview.
In C++, by default template checking was done by instantiation of code, and requrements are in documentation.
Note that much of the requirements of C++ templates is semantic not syntactic; iterators need not only have the proper operations, those operations need to have the proper meaning.
You can check syntactic properties of types in C++ templates. Off the top of my head, there are 6 basic ways.
You can have a traits class requirement, like std::iterator_traits.
You can do SFINAE, an accidentally Turing-complete template metaprogramming technique.
You can use concepts and/or requires clauses if your compiler is modern enough.
You can generate static_asserts to check properties
You can use traits ADL functions, like begin.
You can just duck type, and use it as if it had the properties you want. If it quacks like a duck, it is a duck.
All of these have pluses and minuses.
The downside to all of them is that they can be harder to set up than "this parameter must inherit from the type Foo". Concepts can handle that, only a bit more verbose than Java.
Java style type erasure can be dominated using C++ templates. std::function is an example of a duck typed type eraser that allows unrelated types to be stored as values; doing something as restricted as Java is rarely worthwhile, as the machinery to do it is harder than making something more powerful.
C# reification cannot be fully duplicated by C++, because C#'s runtime environment ships with a compiler, and can effectively compile a new type when you instantiate at runtime. I have seen people ship compilers with C++ programs, compile dynamic libraries, then load and execute them, but that isn't something I'd advise.
Using modern c++20, you can:
template<Number N>
struct Polynomial;
where Number is a concept which checks N (a type) against its properties. This is a bit like the Java signature stuff on steroids.
And by c++23 you'll be able to use compile time reflection to do things that make templates look like preprocessor macros.
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.
Just like the title asks, can C++ class templates take method names as template parameters?
For instance,
template <T>
class Foo
{
public:
void T(int bar);
};
Unfortunately, the C++ core language does not have any means of handling names.
Some possibilities:
Handle names via the preprocessor, ie., ugly macros.
Note: the Boost parameters library uses some undocumented Boost macro trickery that is very relevant here. I used that for a general options class thing once. Sorry I can't remember much about it, but essentially it supports a kind of variadic macros for C++03.
Do your own custom preprocessing, i.e. script based.
Put the burden on the client code programmer, somehow.
For those who wonder, what does one need this for?, a case in point is how to something like Python's library "named tuple" class, in C++, where the programmer provides the names of the tuple members.
I currently use C for numerical computations. I've heard that using C++ Expression Templates is better for scientific computing. What are C++ Expression Templates in simple terms?
Are there books around that discuss numerical methods/computations using C++ Expression Templates?
In what way, C++ Expression Templates are better than using pure C?
What are C++ Expression Templates in simple terms?
Expression templates are a category of C++ template meta programming which delays evaluation of subexpressions until the full expression is known, so that optimizations (especially the elimination of temporaries) can be applied.
Are there books around that discuss numerical methods/computations using C++ Expression Templates?
I believe ET's were invented by Todd Veldhuizen who published a paper on it 15 years ago. (It seems that many older links to it are dead by now, but currently here is a version of it.) Some material about it is in David Vandevoorde's and Nicolai Josuttis' C++ Templates: The Complete Guide.
In what way, C++ Expression Templates are better than using pure C?
They allow you to write your code in an expressive high level way without losing performance. For example,
void f(const my_array<double> a1, const my_array<double> a2)
{
my_array<double> a3 = 1.2 * a1 + a1 * a2;
// ..
}
can be optimized all the way down to
for( my_array<double>::size_type idx=0; idx<a1.size(); ++idx )
a3[idx] = 1.2*a1[idx] + a1[idx]*a2[idx];
which is faster, but harder to understand.
Adding to sbi's answer, expression templates implement high-level peephole optimizations using templates for pattern matching and synthesis.
They also add syntactic sugar, or make your code more readable, by allowing you to specify the algorithm in terms of simple operations. So, in this case, simplicity and elegance are achieved through optimization by metaprogramming. At least, if you do everything right.
There is a nice article on C++ template math in the good old Flipcode archive (sure brings back memories):
http://www.flipcode.com/archives/Faster_Vector_Math_Using_Templates.shtml