How do I define a custom literal suffix for a typeset?

Suppose I have typedef'd a double, and now want to have a literal of this type. How can I achieve this?

1
2
typedef double signalf;
signalf operator""(double val) {return (signalf) val;} // error  


I would have thought this would be simple, but for some reason that won't compile on visual studio 2012. I'm not so much interested in discussing my reasons for doing this (I think the benefits are self evident) but would like to know why this isn't compiling... Thanks.
1. A literal operator must specify a literal suffix identifier.

2. For a non-raw literal operator for floating point types, the parameter must be a long double.

3. A raw literal operator must either have a single const char* parameter
or it must be a variadic template of elements of type char

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
template< char FIRST, char... REST > struct binary
{
    static_assert( FIRST == '0' || FIRST == '1', "invalid binary digit" ) ;
    enum { value = ( ( FIRST - '0' ) << sizeof...(REST) ) + binary<REST...>::value  } ;
};
 
template<> struct binary<'0'> { enum { value = 0 } ; };
template<> struct binary<'1'> { enum { value = 1 } ; };


// raw literal operator 
template<  char... LITERAL > inline
constexpr unsigned int operator "" _b() { return binary<LITERAL...>::value ; }
 
// raw literal operator 
template<  char... LITERAL > inline
constexpr unsigned int operator "" _B() { return binary<LITERAL...>::value ; }
 
// non-raw literal operator 
typedef double signalf;
constexpr signalf operator"" _percent( long double val) { return val / 100 ; }
 
#include <iostream>
 
int main()
{
    std::cout  << 12.34_percent << '\n' // prints 0.1234
               << 10101_B << ", " << 011011000111_b  << '\n' ; // prints 21, 1735
}

http://ideone.com/cTdkex
Oh of course, so this should work then:

signalf operator"" sf_ (double val) {return (signalf) val;} // error

Sadly this still doesn't compile but I just figured out it's because MS C++ doesn't support user defined literals... back to plain old casting for me then...
signalf operator"" sf_ ( /*double*/ long double val) {return (signalf) val;} // *** long double

However, if MS C++ doesn't support user defined literals...
Is there any way to emulate this behaviour using macros? So that I can still get this behaviour;

1
2
3
4
5
6
7
8
9
 
typedef double signalf;
typedef float physf;

//Some macro here that replaces any instance of "_sf" with nothing and every instance of "_pf" with "f" 

signalf val1 = 1.234_sf; // this literal is "1.234" to the compiler and therefore double 
physf val2 = 1.234_pf; // this literal is "1.234f" to the compiler and therefore float


This would be a nice intermediate solution because I could just swap the macro over for the literal overload and wouldn't have to wade through my entire program once Microsoft does implement user defined literals...
Why don't you just do this?

1
2
3
4
5
6
7
8
9
10
11
12
typedef double signalf;
typedef float physf;

inline signalf sf( double d ) { return d ; }

inline physf pf( double d ) { return d ; }

int main()
{
    auto val1 = sf(1.234) ;
    auto val2 = pf(1.234) ;
}
That could work. Thanks :)
Topic archived. No new replies allowed.