Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

const-reference qualified member function

Tags:

c++

c++11

The stock example of a reference-qualified member function seems to be something like this:

#include <stdio.h>
#include <stdexcept>
#include <string>

// Easy access to literals
using namespace std::literals;

// File wrapper
class File {
  private:
    //  The wrapped file
    FILE *_file;
  public:
    File(const char *name) : 
        _file(fopen(name, "r")) { 
        // unable to open the file?
        if (!_file) throw std::runtime_error{ "Unable to open file: "s + name };
    } 
    ~File() { 
        fclose(_file);
    } 

    //  Convert to the underlying wrapped file
    operator FILE *() & { 
        return _file;
    } 

    // TODO: Member functions for working with the file
};

This works well. It is not possible to retrieve the underlying FILE pointer from an unnamed temporary directly. However, if we make the casting operator also const-qualified, this no longer seems to work.

Different compilers simply swallow it without complaint even though it's a terribly useful idea. Take, for example the std::string::c_str() member function. You feel it should be reference-qualified (because otherwise you have an invalid pointer) yet it isn't.

Is this a hole in the C++11 standard? Am I missing something here?

like image 895
Martijn Otto Avatar asked Nov 26 '15 14:11

Martijn Otto


People also ask

What does the const member function qualifier?

The const keyword can be used as a qualifier when declaring objects, types, or member functions. When qualifying an object, using const means that the object cannot be the target of an assignment, and you cannot call any of its non-const member functions.

What are the const member functions?

The const member functions are the functions which are declared as constant in the program. The object called by these functions cannot be modified. It is recommended to use const keyword so that accidental changes to object are avoided. A const member function can be called by any type of object.

What does const reference do?

Const Reference to a pointer is a non-modifiable value that's used same as a const pointer. Here we get a compile-time error as it is a const reference to a pointer thus we are not allowed to reassign it.

What does const after a member function mean?

A constant member function can't modify any non-static data members or call any member functions that aren't constant. To declare a constant member function, place the const keyword after the closing parenthesis of the argument list. The const keyword is required in both the declaration and the definition.


1 Answers

A temporary can be bound to a const& qualified object and the ref-qualifier effectively qualifies the implicitly passed object (*this). If you want to prevent calls on temporaries but allow lvalues, you can = delete the rvalue reference overload and implement the lvalue version. Using const qualified reference qualifiers for both operators requires just one implemented and one = deleted implementation:

class File {
    // ...
    FILE* _file;
public:
    operator FILE*() const&& = delete;
    operator FILE*() const& { return this->_file; }
    // ...
};

The net-effect is that you can use the conversion only for objects to which you go an lvalue:

int main() {
    File       f;
    File const cf{};

    FILE* fp = f;              // OK
    FILE* cfp = cf;            // OK
    FILE* tfp = File();        // ERROR: conversion is deleted
    FILE* mfp = std::move(cf); // ERROR: conversion is deleted  
}
like image 110
Dietmar Kühl Avatar answered Oct 19 '22 11:10

Dietmar Kühl