vendredi 24 septembre 2021

Casting to void to Avoid Use of Overloaded User Defined Comma Operator

I am learning about templates in C++ and came across an example where casting to void is used(shown below).

template<typename T>
auto func (T const& t) -> decltype( (void)(t.size()), T::size_type() )
{
return t.size();

}

In the explanation it is written that

The cast of the expression to void is to avoid the possibility of a user-defined comma operator overloaded for the type of the expressions.

My question(s) is/are:

  1. How can a cast to void be used to avoid the possibility of a user-defined comma operator overloaded for the type of the expressions. I mean can anyone give any example where if we don't use void then this code would give error. For example lets say we have a class called SomeClass which has overloaded the comma operator. Now can this become a problem if we don't use void.
  2. Can static_cast be used in this case instead of C style cast. For example something like static_cast<void>(t.size()) . I am reading examples that use C++17 features and so i wonder why the author has used C style cast in this case.

I have read this from which i get the impression that if we use (void)x; then this means to suppress compiler warnings and also means "ignore the value of x". But then i can't understand the difference between the expression x; and (void)x;.

Is it possible to initialize new std::vector in one line?

I just wonder if it is possible to new and initialize a std::vector at the same time, something like, do the two things in one line:

std::vector<int>* vec = new std::vector<int>(){3, 4};

instead of, first:

std::vector<int>* vec = new std::vector<int>();

then:

vec->push_back(3);
vec->puch_back(4);

Portable way to check whether a floating point division would end in +-inf

I have a floating point division of the form 1.0f / x with x as a float. How would I check beforehand whether the x is so close to 0.0f that the result would be +-inf / undefined? I'm not sure if the epsilon from std limits is enough.

Regards.

Undefined Behavior when using Comma Operator in C++

I am trying to learn how expression are evaluated in C++. So trying out and reading different examples. Below is the code about which i am unable to understand whether it will produce undefined behavior or not. The code is from here. So i guess since they have used it, this must not be UB. But i have my doubts.

#include <iostream>
int main()
{
    int n = 1;
    //std::cout << n << " " << ++n << std::endl;//this is undefined behavior i am sure
    int m = (++n, std::cout << "n = " << n << '\n', ++n, 2*n);//will this also produce UB because here also we have cout in the same manner as above?
    std::cout << "m = " << (++m, m) << '\n';
}

As you can see in the above code, i am sure that the statement:

cout << n << " " << ++n << endl;

produces undefined behavior. My questions are:

  1. But will the same statement used inside the comma operator produce UB(as shown in the code above)? That is, will the below given statement produce UB.
int m = (++n, std::cout << "n = " << n << '\n', ++n, 2*n);
  1. How can we explain what is going on in terms of sequence-before, unsequenced etc the behavior of the above mentioned statement.

PS: I know since C++11 we use sequence-before etc. instead of sequence point so that why i asked the explanation in terms of current standard. I want to know when we use std::cout << n << " " << ++n; outside comma operator it is UB but when we use it inside the comma operator how will it become defined behavior.

CppCoreGuidlines R.33 Why pass `unique_ptr` by reference?

The CppCoreGuidlines rule R.33 suggests to

Take a unique_ptr<widget>& parameter to express that a function reseats the widget.

Reason Using unique_ptr in this way both documents and enforces the function call’s reseating semantics.

Note “reseat” means “making a pointer or a smart pointer refer to a different object.”

I don't understand why we should pass by reference when reseat means "making a pointer or a smart pointer refer to a different object.”

When the function's purpose is to reseat/change the underlying object the pointer is pointing to, aren't we stealing the ownership from the caller this way and therefore should pass the unique_ptr by value, hence moving it and transferring ownership?

Is there an example that explains why passing a unique_ptr by reference is recommended?

jeudi 23 septembre 2021

Make a function has higher precedence than another

So I have a function:

void foo(char a = 'A', int b = 0)
{
    // code
}

And I have another one:

void foo(int b = 0, char a = 'A')
{
    //code
}

Then if I call foo(), it will return an error because the compiler can't decide which function to call. So can I make a function that has higher precedence than another? So if I call foo() then the compiler which one to choose?

C++ Type, Function, and value aliasing for potentially undefined types

Suppose I have two libraries, let's arbitrarily call them "CUDA" and "HIP". These two libraries just so happen to have eerily similar interfaces, and I want to wrap these interfaces into a templated class where the template parameter defines which library is called. So far I have

#define ALIAS_FUNCTION(Alias_,Original_)              \
  template <typename... Args> Alias_(Args&&... args)  \
  -> decltype(Original_(std::forward<Args>(args)...)) \
  { return Original_(std::forward<Args>(args)...);}

enum class Selector {CUDA,HIP};

template <Selector T> struct Interface;

#if (havecuda)
template <>
struct Interface<Selector::CUDA>
{
  using error_type = cudaError_t;
  static const auto success = cudaSuccess;

  ALIAS_FUNCTION(static constexpr getLastError,cudaGetLastError);
};
#endif

#if (havehip)
template <>
struct Interface<Selector::HIP>
{
  using error_type = hipError_t;
  static const auto success = hipSuccess;

  ALIAS_FUNCTION(static constexpr getLastError,hipGetLastError);
};
#endif

While this works it is extremely painful to maintain, as I need to duplicate every alias, as well as make sure a fair chunk of boilerplate is correct. Not to mention the macros. What I want ideally is keep it all in one definition so something like:

template <Selector T>
struct Interface
{
  using error_type = std::conditional<T==Selector::CUDA,cudaError_t,hipError_t>;
  // do something similar to solve the function and variable aliasing
};

but alas std::conditional requires both types to be at least declared. Is there a cleverer solution here? It should ideally also be C++11.