Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deducing the return type of an inline static member function in class definition

I'm trying to create an alias to a return type after an inline function definition to store a member variable. I simplified my situation below (the real type I want to alias is much uglier to type than vector, and the real function more complicated than a one-liner.)

#include <vector>
using namespace std;
struct Test {
    template <typename T>
    static auto GetVector() { return vector<T>(); }

    using VecInt = decltype(GetVector<int>());
    VecInt x;
};

However, clang gives me the following error on the using VecInt line:

error: function 'GetVector' with deduced return type cannot be used before it is defined.

gcc also gives me a similar error. Strangely, this compiles, although it's not useful in my case:

#include <vector>
using namespace std;
struct Test {
    template <typename T>
    static auto GetVector() { return vector<T>(); }

    void dummy() {
        using VecInt = decltype(GetVector<int>());
        VecInt x;
    }
};

Is there a way for me to alias after an inline definition? Alternatively, I can move the GetVector() function on top of the struct, and the code will compile. However, I want to contain it there.

like image 848
Narut Sereewattanawoot Avatar asked Jan 03 '23 01:01

Narut Sereewattanawoot


1 Answers

Ever notice how you can call inline-defined member functions from inside of other member functions, even if the callee is farther down the class than the caller? The reason that works is because the compiler takes inlined definitions of member functions and moves the definitions to the bottom of the class, right after the } part. So you effectively have an implicit forward declaration.

This is not true for type aliases like using declarations. These declarations exist exactly where they are in the class; they cannot reference declarations or definitions that come later in the class.

Since the return value of your function cannot be deduced by the declaration alone, and the actual definition (the thing needed to deduce the return value) lives at the end of the class, your using alias fails to compile. There's not much you can do about this besides declare the function's return value directly. Or declare the type alias as having the desired type, then have the function use that alias.

like image 130
Nicol Bolas Avatar answered Jan 05 '23 16:01

Nicol Bolas