Home > Net >  Making a function in a struct template
Making a function in a struct template

Time:07-11

So i made a template struct cause i want to be able to decide what type i give to my val. But when creating a function i don't know how to do it. Here's what i'm doing:

In my .hpp

template<typename T>
struct Integer
{
    T val;
    void setUint(const T &input);
};

Now i can set what variable i want in the val and what i want in the function.

But now in my cpp i don't know how to invoke the function.

void Integer<T>::setUint(const T &input)
{
    val = input;
}

Error: identifier "T" is undefined.

CodePudding user response:

Syntax is

template <typename T>
void Integer<T>::setUint(const T &input)
{
    val = input;
}

CodePudding user response:

A template function is a way to operate with generic types (you may consider the type as an argument). your template parameters T allows to pass different types to a function whern you invoke it. Please, have a look at the simple example.

#include <iostream>
#include <typeinfo>

// you may put it all in a hpp and thus include the hpp file in the CPP
template<typename T>
struct Integer
{
    T val;
    void setUint(const T &input){
        val=input;
        std::cout <<"the type is " << typeid(T).name() << " value is "<< val << std::endl;
    }
};

// or look at Jarod42's implementation details.
/*
template<typename T>
void Integer<T>::setUint(const T &input){
   val=input;
   std::cout <<"the type is " << typeid(T).name() << " value is "<< val << std::endl;
}*/


// and here you have your cpp calling you template function with different types
int main()
{
    Integer<double> value;
    value.setUint(1500000);

    Integer<int> value2;
    value2.setUint(5);

}

CodePudding user response:

Also for templates, check if T actually matches your expectations. Your template will not make sense for types that are not Integers. Example on how to add these constraints here : https://godbolt.org/z/YsneKe7vj (both C 17 SFINAE, and C 20 concept)

#include <type_traits>
#include <string>

//-----------------------------------------------------------------------------------------------------------
// for C  17 setup a constexpr that will evaluate (at compile time, that's the constexpr bit) 
// if a given type is an integer type
template<typename type_t>
constexpr bool is_integer_type_v = std::is_integral_v<type_t> && !std::is_same_v<type_t,bool>;

// create a template that can optionally be enabled. This is an example of a technique called SFINAE
template<typename type_t, typename enable = void>
struct Integer;

// for C   define a specialization that will succesfully be enabled of integer types only
template<typename type_t>
struct Integer<type_t,std::enable_if_t<is_integer_type_v<type_t>>>
{
    void Set(const type_t v)
    {
        value = v;
    }

    type_t value;
};

//-----------------------------------------------------------------------------------------------------------
// for C  20 use concepts 

template<typename type_t>
concept is_integer = std::is_integral_v<type_t> && !std::is_same_v<type_t, bool>;

// note is_integer now replaces typename, and it can only accept types
// that satisfy the concept
template<is_integer integer_t>
struct IntegerCpp20
{
    void Set(const integer_t v)
    {
        value = v;
    }

    integer_t value;
};

//-----------------------------------------------------------------------------------------------------------

int main()
{
    //Integer<std::string> value; // will not compile;
    Integer<int> value;
    value.Set(2);

    //IntegerCpp20<std::string> value; // will not compile;
    IntegerCpp20<int> value20;
    value20.Set(20);

    return 0;
}
  • Related