In this declaration
std::vector<float> priorities{numqueues, 1.f };
the compiler uses the initializer list constructor.
vector(initializer_list<T>, const Allocator& = Allocator());
The narrowing conversion for initializer lists is prohibited.
In this declaration
std::vector<float> priorities(numqueues, 1.f );
the compiler uses the constructor that specifies the number of elements and their initializer.
vector(size_type n, const T& value, const Allocator& = Allocator());
From the C++ 14 Standard (8.5.4 List-initialization)
2 A constructor is an initializer-list constructor if its first
parameter is of type std::initializer_list or reference to possibly
cv-qualified std::initializer_list for some type E, and either
there are no other parameters or else all other parameters have
default arguments (8.3.6). [ Note: Initializer-list constructors are
favored over other constructors in list-initialization
and (13.3.1.7 Initialization by list-initialization)
1 When objects of non-aggregate class type T are list-initialized such
that 8.5.4 specifies that overload resolution is performed according
to the rules in this section, overload resolution selects the
constructor in two phases:
(1.1) — Initially, the candidate functions are the initializer-list
constructors (8.5.4) of the class T and the argument list consists of
the initializer list as a single argument.
(1.2) — If no viable initializer-list constructor is found, overload
resolution is performed again, where the candidate functions are all
the constructors of the class T and the argument list consists of the
lements of the initializer list.
Here is a demonstrative program
#include <iostream>
#include <initializer_list>
struct A
{
A( std::initializer_list<float> )
{
std::cout << "A( std::initializer_list<float> )\n";
}
A( size_t, float )
{
std::cout << "A( size_t, float )\n";
}
};
int main()
{
A a1 { 1, 1.0f };
A a2( 1, 1.0f );
return 0;
}
The program output is
A( std::initializer_list<float> )
A( size_t, float )
As for your appended question then (8.5.4 List-initialization)
7 A narrowing conversion is an implicit conversion
(7.3) — from an integer type or unscoped enumeration type to a
floating-point type, except where the source is a constant
expression and the actual value after conversion will fit into the
target type and will produce the original value when converted back to
the original type, or
So in this list initialization
MyVector<float> foo{ size_t(3), 2.f };
the constant expression size_t( 3 ) that fits into the type float is used.
For example if in the above demonstrative program you will write
size_t n = 1;
A a1{ n, 1.0f };
then the compiler should issue a message about narrowing conversion (at least the MS VS 2019 C++ compiler issues such an error message).