9

I agree the answer in When to use references vs. pointers.
But, I am wondering why C++ defines atomic_load as

template<class T>
T atomic_load(const std::atomic<T> *obj) noexcept;
                                   ^

instead of

template<class T>
T atomic_load(const std::atomic<T> &obj) noexcept;
                                   ^

Can anyone help me?

Caesar
  • 971
  • 6
  • 13
  • 6
    Most likely for uniformity with the [equivalent C interface](http://en.cppreference.com/w/c/atomic/atomic_load). – WhiZTiM Sep 19 '17 at 12:07
  • 1
    @WhiZTiM But, std::atomic is a class template, why does it require to consistent with C? – Caesar Sep 19 '17 at 12:08
  • 1
    It is not strictly required, it is a convenience for the programmer who doesn't have to remember yet another pointless difference. You just need to remember that `atomic_load` takes a pointer, regardless of what base type exactly you are passing. – Matteo Italia Sep 19 '17 at 12:12

1 Answers1

10

The reason why we have these free function templates at all is source compatibility with C11:

#ifdef __cplusplus
#include <atomic>
#define _Atomic(X) std::atomic<X>
#else
#include <stdatomic.h>
#endif

_Atomic(int) c;

int get_c(void) { 
    return atomic_load(&c); 
}

C doesn't have references.

If you don't need that, then c.load() or the implicit conversion to T will work just fine. Just forget that the free function ever existed.

(This is also why the memory_order version of the free function template is called atomic_load_explicit: _Generic-powered macros in C can handle varying argument types, but not varying arity.)

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
T.C.
  • 133,968
  • 17
  • 288
  • 421