variadic template and omp task - c++11

I am looking for a possible solution to wrap elegantly OpenMP task, specially the directives. In OpenMP tasks, argument must be pin with the key word in, out and inout like:
#pragma omp task inout(x) out(y)
plus_equal(x,y); // x+=y
Nice, however I am looking for an automatic solution to avoid to introduce directive for every functions, I am thinking with variadic template:
template<class Functor, class... Args>
void helper (Functor& f, Args&... args){
#pragma in(SOMETHING), inout(SOMETHING ELSE)
f(args...);
}
Objectively the "glue" between the variadic template and the argument should be the const keyword if the argument is const: it is in else it is inout
or out (objectively there is no solution to distinguish in and inout) and then my code becomes:
helper(plus_equal, x,y);
Reading a few posts, it seems possible to extract argument of the variadic template, and it may be possible to extract argument between const and non const using std::is_const.
However I do not know if we can pass something not basic into the directive. I think it should be possible because, it is a macro.
However, I am not sure such solution exists.
Any idea ?
Best,
++t

Related

Initialisation of a std::string seems to generate the same code no matter which initialisation I use (uniform, assignment, etc)

I was experimenting with C++ Insights and I got a result that was surprising to me and which I don't really understand. I was hoping some one can provide some illumination for.
Given this code snippet:
#include <string>
int main()
{
std::string a {"123"};
std::string b = {"123"};
std::string c = "123";
std::string d("123");
}
I was at least expecting a to be initialised differently to c. With c I was expecting some sort of temporary string to be copied and for a I was expecting just the constructor to be called directly.
Here is the link to c++ insights: here (You have to press the "play" button).
Every one of the different ways to initialise a string is the same. This really surprised me. I started with c++17 and then switched to c++11, which produced something more like what I was expecting.
Does this mean that all init types in c++17 are now the same? - is there a name for this, because I thought uniform init was only with the curly braces {} - is everything now uniform init?

Why is there no std equivalent of boost::enable_if?

In C++11, std::enable_if was added to the Standard Library. It is equivalent to boost::enable_if_c whose condition is a bool. This is suitable for rather simple conditions, but as soon as you use predicates that hold their result in a value constant, you have to use the more verbose construct my_predicate<MyArgs>::value to turn it into bool.
This is exactly what boost::enable_if (without _c suffix) was made for.
Why is there no equivalent in Standard Library?
The standard library goes a different route here. C++17 added variable templates shortcuts for all the type traits that return a ::value. The pattern is always
template <typename... Args>
some_trait_v = some_trait<Args...>::value;
For instance you can write
std::enable_if<std::is_same_v<T1,T2>>
Further the argument for enable_if could be the result of constexpr expressions, for instance
std::enable_if<some_constexpr_function<T1,T2>()>
This way is more generic and does not depend on passing something that must have a value member.

When should I use static data members vs. const global variables?

Declaring const global variables has proven useful to determine some functioning parameters of an API. For example, on my API, the minimum order of numerical accuracy operators have is 2; thus, I declare:
const int kDefaultOrderAccuracy{2};
as a global variable. Would it be better to make this a static const public data member of the classes describing these operators? When, in general, is better to choose one over the other?
const int kDefaultOrderAccuracy{2};
is the declaration of a static variable: kDefaultOrderAccuracy has internal linkage. Putting names with internal linkage in a header is obviously an extremely bad idea, making it extremely easy to violate the One Definition Rule (ODR) in other code with external linkage in the same or other header, notably when the name is used in the body of an inline or template function:
Inside f.hpp:
template <typename T>
const T& max(const T &x, const T &y) {
return x>y ? x : y;
}
inline int f(int x) {
return max(kDefaultOrderAccuracy, x); // which kDefaultOrderAccuracy?
}
As soon as you include f.hpp in two TU (Translation Units), you violate the ODR, as the definition is not unique, as it uses a namespace static variable: which kDefaultOrderAccuracy object the definition designates depends on the TU in which it is compiled.
A static member of a class has external linkage:
struct constants {
static const int kDefaultOrderAccuracy{2};
};
inline int f(int x) {
return max(constants::kDefaultOrderAccuracy, x); // OK
}
There is only one constants::kDefaultOrderAccuracy in the program.
You can also use namespace level global constant objects:
extern const int kDefaultOrderAccuracy;
Context is always important.
To answer questions like this.
Also for naming itself.
If you as a reader (co-coder) need to guess what an identifier means, you start looking for more context, this may be supported through an API doc, often included in decent IDEs. But if you didn't provide a really great API doc (I read this from your question), the only context you get is by looking where your declaration is placed.
Here you may be interested in the name(s) of the containing library, subdirectory, file, namespace, or class, and last not least in the type being used.
If I read kDefaultOrderAccuracy, I see a lot of context encoded (Default, Order, Accuracy), where Order could be related for sales or sorting, and the k encoding doesn't say anything to me. Just to make you looking on your actual problem from a different perspective. C/C++ Identifiers have a poor grammar: they are restricted to rules for compound words.
This limitation of global identifiers is the most important reason why I mostly avoid global variables, even constants, sometimes even types. If its the meaning is limited to a given context, define a thing right within this context. Sometimes you first have to create this context.
Your explanation contains some unused context:
numerical operators
minimum precision (BTW: minimum doesn't mean default)
The problem of placing a definition into the right class is not very different from the problem to find the right place for a global: you have to find/create the right header file (and/or namespace).
As a side note, you may be interested to learn that also enum can be used to get cheap compile-time constants, and enums can also be placed into classes (or namespaces). Also a scoped enumeration is an option you should consider before introducing global constants. As with enclosing class definitions, the :: is a means of punctuation which separates more than _ or an in-word caseChange.
Addendum:
If you are interested in providing a useful default behaviour of your operations that can be overridden by your users, default arguments could be an option. If your API provides operators, you should study how the input/output manipulators for the standard I/O streams work.
my guess is that:
const takes up inline memory based on size of data value such as “mov ah, const value” for each use, which can be a really short command, in size overall, overall, based on input value.
whereas static values takes up a whole full data type, usually int, whatever that maybe on the current system for each static, maybe more, plus it may need a full memory access value to access the data, such as mov ah, [memory pointer], which is usually size of int on the system, for each use (with a full class it could even more complex). yet the static is still declared const so it may behave the same as the normal const type.

Why can't declaration-only friend functions have default arguments?

I've learned that the C++11 standard doesn't allow friend functions to have default arguments unless the friend declaration is a definition. So this isn't allowed:
class bar
{
friend int foo(int seed = 0);
};
inline int foo(int seed) { return seed; }
but this is:
class bar
{
friend int foo(int seed = 0)
{
return seed;
}
};
(Example courtesy http://clang-developers.42468.n3.nabble.com/Clang-compile-error-td4033809.html)
What is the rational behind this decision? Friend functions with default arguments are useful, e.g. if the function is too complex to declare in place, why are they now disallowed?
In looking at DR 136, it looks like there are issues when a friend declaration combines with namespace-level declarations with default arguments that makes the semantics hard to reason about (and perhaps difficult to issue quality diagnostics against), especially in the context of templates. The proposed DR resolution given on that page is to only allow default arguments in them when the declaration is the only one in the program. Since a function definition is also a declaration, that would mean the only useful way to specify default arguments in a friend declaration is to make it a definition. I would guess the C++11 standard simply chose to make this practical usage requirement explicit.
(Technically, if by "program" they mean "translation unit", one could construct a complete program where the function were defined in a completely different translation unit, but since this function's definition would not have the class definition visible, the benefits of the friendship grant would be largely useless.)
The workaround for this hiccup seems pretty straightforward. Declare the friend without using default arguments, and then declare it again at namespace scope with whatever default arguments are desired.

What is the best syntax to declare a class as noncopyable?

(assuming I cannot use boost::noncopyable, which was explicitly designed for that purpose)
(assuming I cannot use C++11)
When making a class noncopyable, I usually see the following syntax:
class MyClass
{
public:
...
stuff
...
private:
MyClass(const MyClass&); // disables the copy constructor
MyClass& operator=(const MyClass&); // disables the copy assignment operator
};
This syntax seems long-winded. I think that I can use the following instead:
MyClass(MyClass&); // disables the copy constructor
void operator=(MyClass); // disables the copy assignment operator
This seems shorter (it repeats the name of the class just 3 times instead of 4 times; it also omits const and &).
Does my syntax do exactly the same thing as the other syntax?
Is there any reason to prefer one over the other?
Putting the emphasize on shortening the source code a few words is not very good. Besides, you are making your operator= unreadible, it is no copy-operator anymore...
You should refrain from using the latter just to save a few words.
There is a post here, stating
//QUOTE
class MyClass
{
private:
MyClass(const MyClass&) {}
MyClass& operator=(const MyClass&) {}
};
If you are a C++ programmer who has read an introductory text on C++, but has little exposure to idiomatic C++ (ie: a lot of C++ programmers), this is... confusing. It declares copy constructors and copy assignment operators, but they're empty. So why declare them at all? Yes, they're private, but that only raises more questions: why make them private?
To understand why this prevents copying, you have to realize that by declaring them private, you make it so that non-members/friends cannot copy it. This is not immediately obvious to the novice. Nor is the error message that they will get when they try to copy it.
//QUOTE END

Resources