Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7188099
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 28, 20262026-05-28T18:59:31+00:00 2026-05-28T18:59:31+00:00

In C++03, Boost’s Foreach, using this interesting technique , can detect at run-time whether

  • 0

In C++03, Boost’s Foreach, using this interesting technique, can detect at run-time whether an expression is an lvalue or an rvalue. (I found that via this StackOverflow question: Rvalues in C++03 )

Here’s a demo of this working at run-time

(This is a more basic question that arose while I was thinking about this other recent question of mine. An answer to this might help us answer that other question.)

Now that I’ve spelled out the question, testing rvalue-ness in C++03 at compile-time, I’ll talk a little about the things I’ve been trying so far.

I want to be able to do this check at compile-time. It’s easy in C++11, but I’m curious about C++03.

I’m trying to build upon their idea, but would be open to different approaches also. The basic idea of their technique is to put this code into a macro:

true ? rvalue_probe() : EXPRESSION;

It is ‘true’ on the left of the ?, and therefore we can be sure that EXPRESSION will never be evaluated. But the interesting thing is that the ?: operator behaves differently depending on whether its parameters are lvalues or rvalues (click that link above for details). In particular, it will convert our rvalue_probe object in one of two ways, depending on whether EXPRESSION is an lvalue or not:

struct rvalue_probe
{
    template< class R > operator       R () { throw "rvalue"; }
    template< class L > operator       L & () const { throw "lvalue"; }
    template< class L > operator const L & () const { throw "const lvalue"; }
};

That works at runtime because the thrown text can be caught and used to analyze whether the EXPRESSION was an lvalue or an rvalue. But I want some way to identify, at compile-time, which conversion is being used.

Now, this is potentially useful because it means that, instead of asking

Is EXPRESSION an rvalue?

we can ask:

When the compiler is compiling true ? rvalue_probe() : EXPRESSION, which of the two overloaded operators, operator X or operator X&, is selected?

( Ordinarily, you could detect which method was called by changing the return types and getting the sizeof it. But we can’t do that with these conversion operators, especially when they’re buried inside the ?:. )

I thought I might be able to use something like

is_reference< typeof (true ? rvalue_probe() : EXPRESSION) > :: type

If the EXPRESSION is an lvalue, then the operator& is selected and I hoped that the whole expression would then be a & type. But it doesn’t seem to work. ref types and non-ref types are pretty hard (impossible?) to distinguish, especially now that I’m trying to dig inside a ?: expression to see which conversion was selected.

Here’s the demo code pasted here:

#include <iostream>
using namespace std;
struct X {
        X(){}
};

X x;
X & xr = x;
const X xc;

      X   foo()  { return x; }
const X   fooc() { return x; }
      X & foor()  { return x; }
const X & foorc() { return x; }

struct rvalue_probe
{
        template< class R > operator       R () { throw "rvalue"; }
        // template< class R > operator R const () { throw "const rvalue"; } // doesn't work, don't know why
        template< class L > operator       L & () const { throw "lvalue"; }
        template< class L > operator const L & () const { throw "const lvalue"; }
};

typedef int lvalue_flag[1];
typedef int rvalue_flag[2];
template <typename T> struct isref     { static const int value = 0; typedef lvalue_flag type; };
template <typename T> struct isref<T&> { static const int value = 1; typedef rvalue_flag type; };

int main() {
        try{ true ? rvalue_probe() : x;       } catch (const char * result) { cout << result << endl; } // Y lvalue
        try{ true ? rvalue_probe() : xc;      } catch (const char * result) { cout << result << endl; } // Y const lvalue
        try{ true ? rvalue_probe() : xr;      } catch (const char * result) { cout << result << endl; } // Y       lvalue
        try{ true ? rvalue_probe() : foo();   } catch (const char * result) { cout << result << endl; } // Y rvalue
        try{ true ? rvalue_probe() : fooc();  } catch (const char * result) { cout << result << endl; } // Y rvalue
        try{ true ? rvalue_probe() : foor();  } catch (const char * result) { cout << result << endl; } // Y lvalue
        try{ true ? rvalue_probe() : foorc(); } catch (const char * result) { cout << result << endl; } // Y const lvalue

}

(I had some other code here at the end, but it’s just confusing things. You don’t really want to see my failed attempts at an answer! The above code demonstrates how it can test lvalue-versus-rvalue at runtime.)

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-28T18:59:32+00:00Added an answer on May 28, 2026 at 6:59 pm

    It took some effort, but here’s a tested and working is_lvalue macro that correctly handles const struct S function return types. It relies on const struct S rvalues not binding to const volatile struct S&, while const struct S lvalues do.

    #include <cassert>
    
    template <typename T>
    struct nondeducible
    {
      typedef T type;
    };
    
    char (& is_lvalue_helper(...))[1];
    
    template <typename T>
    char (& is_lvalue_helper(T&, typename nondeducible<const volatile T&>::type))[2];
    
    #define is_lvalue(x) (sizeof(is_lvalue_helper((x),(x))) == 2)
    
    struct S
    {
      int i;
    };
    
    template <typename T>
    void test_()
    {
      T a = {0};
      T& b = a;
      T (* c)() = 0;
      T& (* d)() = 0;
      assert (is_lvalue(a));
      assert (is_lvalue(b));
      assert (!is_lvalue(c()));
      assert (is_lvalue(d()));
    }
    
    template <typename T>
    void test()
    {
      test_<T>();
      test_<const T>();
      test_<volatile T>();
      test_<const volatile T>();
    }
    
    int main()
    {
      test<int>();
      test<S>();
    }
    

    Edit: unnecessary extra parameter removed, thanks Xeo.

    Edit again: As per the comments, this works with GCC but relies on unspecified behaviour in C++03 (it’s valid C++11) and fails some other compilers. Extra parameter restored, which makes it work in more cases. const class rvalues give a hard error on some compilers, and give the correct result (false) on others.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Using boost build, if I can link to a boost python library with this
A boost TCP acceptor can be wired up by using an endpoint constructor that
Boost Network I am trying out this code in a small console app on
Boost lambda allows to overwrite deduced return type using ret<T> template. I have tried
boost::tuple has a get() member function used like this: tuple<int, string, string> t(5, foo,
Using Boost.Spirit, is it possible to deliver a terminal token to multiple actions and
I've been using Boost as a framework built from Pete Goodliffe's script for quite
I'm using Boost asio to send and receive framed TCP messages. Does anyone know
Boost Spirit library permits to Track the Input Position While Parsing . This mechanism
Using Boost Program Options, how do you get the string equivalent of argv[0]?

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.