Search code examples
c++c++20initializer-liststdarraybinary-semaphore

error: too many initializers for ‘std::array<std::counting_semaphore<1>, 4>’


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?


Solution

  • 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 } 
        };