'defining floating point constants based on deduced type

I have a function template that takes in a 3D vector (anything that has a bracket operator and three elements: MyCustom3DVector, float[3], double*, etc.) and computes something from it. The signature looks like that:

template <typename Vec3> 
constexpr auto compute_stuff(const Vec3& v);

In this function, I need to define the constant 1/5. The issue is that the underlying type could be either float or double. I somehow need to extract the underlying type of my Vec3. I can do so using

using T = std::remove_reference_t<decltype(std::declval<Vec3>()[0])>;
constexpr auto oneFifth = T{1.0/5.0};

but this looks ugly and unnecessarily complicated. Is there a better way to proceed?



Solution 1:[1]

I would write a type trait for this.

Assuming you want to support pointers to first element of an array, containers that do have a value_type and a limited number of containers that do not have a value_type member alias:

#include <type_traits>
#include <iostream>
#include <vector>

template <typename T,typename = void> struct value_type;
// either its a pointer
template <typename T> struct value_type<T*,void> { using type = T; };
// or it has value_type
template <typename T> struct value_type<T,std::void_t<typename T::value_type>> { using type = typename T::value_type;};

// for convenience
template <typename T> using value_type_t = typename value_type<T>::type;

// ..or it doesn't have a value_type member alias
// some custom container
struct my_vector {
    // no value_type 
    double* data;
};    
// specialization for custom container
template <> struct value_type<my_vector> { using type = double;};


int main()
{
    std::cout << std::is_same_v< int,value_type_t<std::vector<int>>>;
    std::cout << std::is_same_v<double,value_type_t<double*>>;
    std::cout << std::is_same_v<double,value_type_t<my_vector>>;

    // oneFifth
    value_type_t<my_vector> oneFifth{1.0/5.0};
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 463035818_is_not_a_number