vendredi 2 juin 2017

Passing template argument reference type to nested template structure does not work

I am puzzled, I was designing a template and I found a strange behavior regarding instantiating the template with T=float&:

// Given an available float f:
float f = 1.0;

// This getter works for T=float&:
template <typename T>
struct test {
  const T get() { return f; }
};

int main() {
  float& f1 = test<float&>().get();
}

The first strange thing is that f1 should be const float& for the code to be correct, and thus, I would expect an error, but it works fine.

The second strange thing is on this similar example that reports an error when I would expect it not to:

// Given an available float f:
float f = 1.0;

struct State {
  const float& get() { return f; }
};

// This does not work for T=float&:
template <typename T>
struct test2 {
  State state;
  const T get() { return state.get(); }
};

int main() {
  const float& f2 = test2<float&>().get();
}

The error reported is this:

main.cpp: In instantiation of 'const T test2<T>::get() [with T = float&]':
main.cpp:31:41:   required from here
main.cpp:22:36: error: binding reference of type 'float&' to 'const float' discards qualifiers
   const T get() { return state.get(); }

Which is strange, since the second example only declared const float& types, not float& and not const float, so I don't know what is happening.

Maybe templates were not designed to work with references or its a bug on GCC or I am just doing something dumb.

I tested this code using gcc (GCC) 6.3.1 20170306 and also on repl.it website using C++11.

Aucun commentaire:

Enregistrer un commentaire