C++ Elegant way to implement assignment of different type using one method and without warning?
Asked Answered
C

2

5

I have to implement basically the same function but for different size. Specifically it is something like...

type& operator=(unsigned int);
type& operator=(unsigned long int);
type& operator=(unsigned long long int);
type& operator=(int);
type& operator=(long int);
type& operator=(long long int);
type& operator=(short int);
//so on and so forth...

They have to do exactly the same thing... (except i should take into account the different size), the main idea would be "if the type is the widest use the code for the task... otherwise perform a casting and execute the code". Is it possible to avoid all such repetitive code by using only one method? (i just don't want the compiler throw me some warning when i compile...).

Thank you

Cartesian answered 23/9, 2015 at 10:30 Comment(2)
Assignment from primitive integer types is problematic for various reasons, but if you must do it: have you tried just implementing the overloads for intmax_t and uintmax_t (from <cstdint>)?Sexism
Yes i'm using cstdint, i just want to avoid to write all the same code... in elegant and efficient way.Cartesian
F
6

This will work for all integral types:

template<
    typename T,
    typename = std::enable_if_t<std::is_integral<T>::value>
>
type& operator= (T);

If you want to depend on size, it can be obtained with simply sizeof(T). You can compare that with your biggest desired size.

If you wanted two separate functions, you'd need to put that clause in as well and use some sort of static-all.

Fattish answered 23/9, 2015 at 10:33 Comment(16)
Is there any alternative to templates? they're pretty hard to read.Cartesian
@Lukkio Excuse me, but what do you find hard to read in this particular code? I think it's pretty straightforward.Fattish
Could you forward me some reference on template syntax? My max in using template is <code>template <class T></code> or i specify a specific type for T.Cartesian
@Lukkio This link might help, as well as type_traits documentation.Fattish
@BartekBanachewicz typename std::enable_if<sizeof(T) == sizeof(long long)>::type* = nullptr should work.Fonteyn
Or you could just have another overload which would be preferred to the templateFonteyn
@Fonteyn what do you mean?Cartesian
@BartekBanachewicz your use of template, your specific use i mean, is a feature of C++11, isn't?Cartesian
@Lukkio enable_if_t was added in C++14.Fattish
@BartekBanachewicz i don't understand the semantic of the syntax you've used. If i putted <code>template <class T, class V></code> it means i'm parametrizing two types what have you putted in the second argument of your template is a kind a proposition without a name i can't understand how to intepret it (but the idea is clear).Cartesian
you can drop the typename enable_if_t since the _t already extracts the ::typeSnick
@Lukkio this is just a way to put that clause in. SFINAE requires the function type to contain the check as either template parameter, return type or a parameter type. Either would work, I just prefer this form.Fattish
I prefer the anser by @SimonKraemer because it allows multiple overloads. Using SFINAE on default function template arguments is only for cases where you want to restrict to a single subset.Snick
@BartekBanachewicz so actually your code (very informally) should mean "apply the template if T is of integral type", isn't? you defined a parameter in the first argument, on the second you defined a kind of constraint on it ,is it?Cartesian
would be possible to add a further condition that check the type is signed or not? if it is signed i would like to generate some code (the templates are a kind of macro afaik) otherwise generate other code.Cartesian
@Lukkio yes, it is possible to check if the type is signed or not using something like std::is_signed. Please ask another question if you have issues implementing this.Fonteyn
M
6

In addition to the answer of Bartek Banachewicz an alternative way to solve it:

struct type
{
    ////Solution by Bartek Banachewicz
    //template<typename T,typename = typename std::enable_if<std::is_integral<T>::value>::type>
    //type& operator= (T) 
    //{ 
    //  return *this; 
    //}

    template<typename T>
    auto operator=(T) -> typename std::enable_if<std::is_integral<T>::value, type>::type&
    {
        return *this;
    }
};
Motel answered 23/9, 2015 at 10:45 Comment(2)
I feel that this link https://mcmap.net/q/116743/-arrow-operator-gt-in-function-heading might be useful to those who (like me), don't know about the -> syntax in signatures.Aaberg
this answer is better because it allows multiple std::enable_if overloads (you can't change the default function template argument )Snick

© 2022 - 2024 — McMap. All rights reserved.