2

The below code snippet does not compile. I tried different initializers but could not make it compile.

#include <array>
#include <semaphore>


int main()
{
    std::array<std::binary_semaphore, 4> semaphores { {0}, {0}, {0}, {0} };
    auto& [ lock1, lock2, lock3, lock4 ] { semaphores };
}

Here's the error message:

SO.cpp:8:74: error: too many initializers for ‘std::array<std::counting_semaphore<1>, 4>’
    8 |     std::array<std::binary_semaphore, 4> semaphores { {0}, {0}, {0}, {0} };
      |                                                                          ^

Isn't it possible to declare an array of binary_semaphores? What is the correct syntax for this?

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
digito_evo
  • 3,216
  • 2
  • 14
  • 42

2 Answers2

6

In general you could write for example adding one more pair of braces like

std::array<std::binary_semaphore, 4> semaphores { { {0}, {0}, {0}, {0} } };

Otherwise the first initializer {0} is considered as an initializer of the whole object of the std::array type.

However there is another problem. The constructor is explicit.

constexpr explicit counting_semaphore(ptrdiff_t desired);

So you need to use the explicit constructor in the initializers.

For example

    std::array<std::binary_semaphore, 4> semaphores 
    { 
        { 
            std::binary_semaphore{ 0 }, 
            std::binary_semaphore{ 0 }, 
            std::binary_semaphore{ 0 }, 
            std::binary_semaphore{ 0 } 
        }
    };

In this case you may also write without introducing the additional braces like

    std::array<std::binary_semaphore, 4> semaphores 
    { 
            std::binary_semaphore{ 0 }, 
            std::binary_semaphore{ 0 }, 
            std::binary_semaphore{ 0 }, 
            std::binary_semaphore{ 0 } 
    };
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
1

It appears that the problem is related to the explicit constructor for std::binary_semaphore.

The below code compiles:

#include <array>
#include <semaphore>


int main()
{
    std::array<std::binary_semaphore, 4> semaphores { std::binary_semaphore { 0 }, std::binary_semaphore { 0 },
                                                      std::binary_semaphore { 0 }, std::binary_semaphore { 0 } };
    auto& [ lock1, lock2, lock3, lock4 ] { semaphores };
}

It doesn't look neat though.

digito_evo
  • 3,216
  • 2
  • 14
  • 42