0

This question is a followup after this one. The actual problem is that default template parameters for function templates are not supported by Visual Studios 2012 as indicated by this list.


Since default template parameters are not supported by Visual Studios 2012, is there any workaround to have the same result without it? So is it possible to define a template function such as

template <typename T, typename Ret = T>
Ret round(T val, Ret ret = Ret()) {
    return static_cast<Ret>(
        (val >= 0) ?
        floor(val + (T)(.5)) :
        ceil( val - (T)(.5))
    );
}

without the use of default template arguments? The function works as

auto a = round(5.5, int()); // int a = 6
auto b = round(5.5); // double b = 6.0
Community
  • 1
  • 1
Didii
  • 1,194
  • 12
  • 36

1 Answers1

1

Like this, also, passing a value to force a return type is not really a nice way to do it, use the template argument instead :

#include <iostream>
#include <cmath>

template <typename Ret, typename T>
Ret round( T val ) {
    return static_cast<Ret>(
        ( val >= 0 ) ?
        std::floor( val + (T) ( .5 ) ) :
        std::ceil( val - (T) ( .5 ) )
        );
}

template <typename T>
T round( T val ) {
    return round<T,T>( val );
}

auto a = round<int>( 5.5 ); // int a = 6
auto b = round( 5.5 ); // double b = 6.0

static_assert( std::is_same<decltype(a), int>::value, "a must be int" );
static_assert( std::is_same<decltype(b), double>::value, "b must be double" );

int main() {
    std::cout << a << " " << b; 
}
galop1n
  • 8,573
  • 22
  • 36
  • Thanks! This is an answer to both of my questions. I inserted `round(val)` as return value for the overloaded function which resulted in a compiler error. I linked this answer to the previous question. – Didii Feb 16 '14 at 13:28
  • 2
    Curious, `round(5)` calls which? – Yakk - Adam Nevraumont Feb 16 '14 at 13:53
  • An ambiguous call… As this is a workaround to a missing feature and calling round with an integer input would probably be an error, i would use `template auto round( T val ) -> typename std::enable_if< std::is_floating_point::value, T>::type;` instead, and a static_assert in the 2 arguments version to enforce T to be a floating point value. – galop1n Feb 16 '14 at 14:05