Nix
Nix

Reputation: 451

How to use is_arithmetic taking an universal reference?

Playing with variadic templates I made functions that sums elements.

It works well but I wanted to add a type_trait test to check if all arguments passed are numeric types.

It works if i give r values but it blocks if i give lvalues.

    sum.h

#ifndef SUM_H_INCLUDED
#define SUM_H_INCLUDED

#include<type_traits>

template <typename T>
double sums_(T && arg)
{
    static_assert(std::is_arithmetic<T>::value,"Only numbers !");
    return arg;
}

template <typename T, typename ... Args>
double sums_(T && val, Args &&... args)
{
    return sums_(std::forward<T>(val)) + sums_(std::forward<Args>(args)...);
}

template <typename ... Args>
double sums(Args &&... args)
{
    return sums_(std::forward<Args>(args)...);
}


#endif // SUM_H_INCLUDED

    main.cpp

#include <iostream>
#include "sum.h"


int main()
{

    //works
    std::cout << sums(42.30,28) << std::endl;

    int x = 100;
    //error
    std::cout << sums(42.30,28,x) << std::endl;

    return 0;
}

It seems normal, since is_arithmetic::value = false for a reference on a numeric type (http://en.cppreference.com/w/cpp/types/is_arithmetic). But, how could I test that my variables are numeric in the case of a universal reference ?

Upvotes: 0

Views: 281

Answers (1)

HolyBlackCat
HolyBlackCat

Reputation: 96579

You want

std::is_arithmetic<std::remove_reference_t<T>>

since a forwarding reference makes T either a reference to a possibly cv-qualified type or a such type itself, and is_arithmetic already handles cv-qualifiers.

Upvotes: 3

Related Questions