Date: Sun, 1 May 2022 11:06:17 +0200
On 01/05/2022 09.46, Abdullah Qasim via Std-Proposals wrote:
> How about:
>
>
>
> explicit template <typename T, typename U, typename ...V>
>
> T Func(U u, V... v)
>
>
>
> ??
If "Func" is a constructor, how do you differentiate between
the current meaning of "explicit" on a constructor and the
new meaning?
Jens
> *From: *Frederick Virchanza Gotham via Std-Proposals <mailto:std-proposals_at_[hidden]>
> *Sent: *30 April 2022 13:07
> *To: *std-proposals <mailto:std-proposals_at_[hidden]>
> *Cc: *Frederick Virchanza Gotham <mailto:cauldwell.thomas_at_[hidden]>
> *Subject: *Re: [std-proposals] Explicit keyword for template parameters
>
>
>
> On Fri, Mar 25, 2022 at 11:09 AM organicoman wrote:
>>
>> Your proposal could be interesting.
>> But why do you want to explicitly write the type, if you can deduce it?
>
>
> One common debacle in C++ is unwanted integer promotion, especially
> for beginner programmers. Let's say we have a template function whose
> return type is the same as its parameter type:
>
> template<typename T>
> T Func(T const &arg) { /* Do something */ }
>
> And let's say we do this:
>
> int main(void)
> {
> char unsigned a = 7, b = 6;
>
> Func( a + b );
> }
>
> Lots of people at first glance will think here that 'Func' is being
> instantiated with the type "char unsigned", when really it's being
> instantiated with "int".
> If the template function, 'Func', will be frequently used in such a
> context, it would be better for the programmer to have to explicitly
> specify the type, either:
>
> Func<char unsigned>(a+b);
>
> or even:
>
> Func<decltype(a)>(a+b);
>
> In my day job I write C++ for an Arduino microcontroller. I went
> looking in my code just now to find the template function I wrote
> earlier this month. The following function performs the mathematical
> operation:
>
> a + b
>
> however if this operation results in overflow then it returns:
>
> std::numeric_limits<T>::max();
>
> So here's how I wrote the function:
>
> #include <type_tratis>
>
> template<typename T>
> typename std::common_type<T>::type Add_Or_Max(T const a, T const b)
> {
> static_assert( false == std::numeric_limits<T>::is_signed,
> "Add_Or_Max can only be used with an unsigned integer type" );
>
> if ( a > (std::numeric_limits<T>::max() - b) )
> {
> return std::numeric_limits<T>::max();
> }
> else
> {
> return a + b;
> }
> }
>
> My program runs on an Arduino microcontroller, however I also compile
> it as part of a simulator that runs on an x86_64 desktop PC. In the
> future the simulator might run on a different kind of desktop PC, and
> we might change to a 16-Bit or 64-Bit microcontroller (or even 8-Bit
> -- Arduino has a C++ compiler for 8-Bit). Because of the differences
> in architecture here, I am very particular about integer types, using
> "std::uint16_t" and "std::int32_t" instead of short, int, long (and
> also watching out for the perils of integer promotion -- e.g. uint32_t
> might promote to a signed 64-Bit number). When a programmer uses my
> function "Add_Or_Max", I want it to stick out like a sore thumb in the
> code which integer type they're using, e.g.:
>
> #include <cstdint>
> using std::uint16_t;
>
> uint16_t my_global_var;
>
> int main(void)
> {
> Add_Or_Max( my_global_var, 52u ); // I don't want this to compiler
>
> Add_Or_Max<uint16_t>( my_global_var, 52u ); // I want this to compile
> }
>
> And so I think it would be great if we could have explicit template
> parameters as follows:
>
> template<explicit typename T>
> T Add_Or_Max(T const a, T const b)
> {
> static_assert( false == std::numeric_limits<T>::is_signed,
> "Add_Or_Max can only be used with an unsigned integer type" );
>
> if ( a > (std::numeric_limits<T>::max() - b) )
> {
> return std::numeric_limits<T>::max();
> }
> else
> {
> return a + b;
> }
> }
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals <https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals>
>
>
>
>
> How about:
>
>
>
> explicit template <typename T, typename U, typename ...V>
>
> T Func(U u, V... v)
>
>
>
> ??
If "Func" is a constructor, how do you differentiate between
the current meaning of "explicit" on a constructor and the
new meaning?
Jens
> *From: *Frederick Virchanza Gotham via Std-Proposals <mailto:std-proposals_at_[hidden]>
> *Sent: *30 April 2022 13:07
> *To: *std-proposals <mailto:std-proposals_at_[hidden]>
> *Cc: *Frederick Virchanza Gotham <mailto:cauldwell.thomas_at_[hidden]>
> *Subject: *Re: [std-proposals] Explicit keyword for template parameters
>
>
>
> On Fri, Mar 25, 2022 at 11:09 AM organicoman wrote:
>>
>> Your proposal could be interesting.
>> But why do you want to explicitly write the type, if you can deduce it?
>
>
> One common debacle in C++ is unwanted integer promotion, especially
> for beginner programmers. Let's say we have a template function whose
> return type is the same as its parameter type:
>
> template<typename T>
> T Func(T const &arg) { /* Do something */ }
>
> And let's say we do this:
>
> int main(void)
> {
> char unsigned a = 7, b = 6;
>
> Func( a + b );
> }
>
> Lots of people at first glance will think here that 'Func' is being
> instantiated with the type "char unsigned", when really it's being
> instantiated with "int".
> If the template function, 'Func', will be frequently used in such a
> context, it would be better for the programmer to have to explicitly
> specify the type, either:
>
> Func<char unsigned>(a+b);
>
> or even:
>
> Func<decltype(a)>(a+b);
>
> In my day job I write C++ for an Arduino microcontroller. I went
> looking in my code just now to find the template function I wrote
> earlier this month. The following function performs the mathematical
> operation:
>
> a + b
>
> however if this operation results in overflow then it returns:
>
> std::numeric_limits<T>::max();
>
> So here's how I wrote the function:
>
> #include <type_tratis>
>
> template<typename T>
> typename std::common_type<T>::type Add_Or_Max(T const a, T const b)
> {
> static_assert( false == std::numeric_limits<T>::is_signed,
> "Add_Or_Max can only be used with an unsigned integer type" );
>
> if ( a > (std::numeric_limits<T>::max() - b) )
> {
> return std::numeric_limits<T>::max();
> }
> else
> {
> return a + b;
> }
> }
>
> My program runs on an Arduino microcontroller, however I also compile
> it as part of a simulator that runs on an x86_64 desktop PC. In the
> future the simulator might run on a different kind of desktop PC, and
> we might change to a 16-Bit or 64-Bit microcontroller (or even 8-Bit
> -- Arduino has a C++ compiler for 8-Bit). Because of the differences
> in architecture here, I am very particular about integer types, using
> "std::uint16_t" and "std::int32_t" instead of short, int, long (and
> also watching out for the perils of integer promotion -- e.g. uint32_t
> might promote to a signed 64-Bit number). When a programmer uses my
> function "Add_Or_Max", I want it to stick out like a sore thumb in the
> code which integer type they're using, e.g.:
>
> #include <cstdint>
> using std::uint16_t;
>
> uint16_t my_global_var;
>
> int main(void)
> {
> Add_Or_Max( my_global_var, 52u ); // I don't want this to compiler
>
> Add_Or_Max<uint16_t>( my_global_var, 52u ); // I want this to compile
> }
>
> And so I think it would be great if we could have explicit template
> parameters as follows:
>
> template<explicit typename T>
> T Add_Or_Max(T const a, T const b)
> {
> static_assert( false == std::numeric_limits<T>::is_signed,
> "Add_Or_Max can only be used with an unsigned integer type" );
>
> if ( a > (std::numeric_limits<T>::max() - b) )
> {
> return std::numeric_limits<T>::max();
> }
> else
> {
> return a + b;
> }
> }
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals <https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals>
>
>
>
>
Received on 2022-05-01 09:06:21