Search code examples
c++templatesc++14rvalue-reference

Why rvalue reference template variable is able to bind to lvalue


Why rvalue reference template variable b<int> is able to bind to lvalue a?

#include <iostream>

int a = 3;

template<typename T>
T&& b = a;

int main() {
    if(std::is_same_v<decltype(b<int>), int&&>) {
        std::cout << "same\n";
    } else {
        std::cout << "different\n";
    }
}
Output: same

Solution

  • Why rvalue reference template variable b<int> is able to bind to lvalue a?

    This question makes an incorrect assumption. An rvalue reference b<int> is not able to bind to a. With your implementation, there is no error because decltype(b<int>) itself does not cause the instantiation of b<int>.

    Whether this is ok or not is a bit unclear. The corresponding quote from the C++17 draft standard is as follows [temp.inst/6]:

    Unless a variable template specialization has been explicitly instantiated or explicitly specialized, the variable template specialization is implicitly instantiated when the specialization is used.

    According to this quote, I think that b should be instantiated, since b<int> is used (even though in an unevaluated context).

    However, in the current draft, the wording is different [temp.inst/7/1]:

    Unless a variable template specialization is a declared specialization, the variable template specialization is implicitly instantiated when it is referenced in a context that requires a variable definition to exist or if the existence of the definition affects the semantics of the program.

    Anyway, once you ensure the instance is required, the you will get a compilation error.

    Live demo: https://godbolt.org/z/Ws5ajxWYM