Search code examples
c++c++11c++14autodecltype

decltype(auto) with multiple returning types using C++14


I installed the CTP-Nov2013-Compiler to get familiar/experiment with some C++14 features(learning by doing/reading) for VS 2013. I tried something like a string to any POD-type converter without using generic methods which failed due to the error (cannot spell the correct error beacuse since today I made somehow Visual Studio to crash whenever I try to build the program[CTP bug?]) 'return type is not of the first return type'.

An example of the problem:

#include <iostream>

using namespace std;

enum EType{
    eInt,
    eBool,
    eFloat,
    eString
}

class Test
{
    Test();
    virtual ~Test(){}

    decltype(auto) SomeMethod(std::string texttoconvert, EType type)
    {
        switch(type)
        {
            //convert to the specific type by using the C++11 stoi* functions and return it (for the example I'm not checking for failure in the conversion)
            case eInt: return std::stoi(texttoconvert);
            break;
            case eFloat: return std::stof(texttoconvert);
            break;
            ...
            default:
            break;
        }
    }


int main()
{
    Test hugo;
    auto lAuto=hugo.SomeMethod("1.234", eFloat);
    cout<<lAuto<<endl; //should return a float
    return 0;
}

So the question is, is the error of logical kind (except not using try-catch-blocks for the std::sto* conversion) or is it a syntax error?

Another problem I have, is that I had to implement the method in the header file(else I got an error) and not in the .cpp file, is this a wanted/necessary feature like for template functions?


Solution

  • You need to pass compile-time information as a template parameter.

    And type determining information must be compile-time information.

    enum EType{
      eInt,
      eBool,
      eFloat,
      eString
    };
    
    template<EType type>
    decltype(auto) convert(std::string texttoconvert);
    
    template<>
    decltype(auto) convert<eInt>(std::string texttoconvert) {
      return std::stoi(texttoconvert);
    }
    template<>
    decltype(auto) convert<eFloat>(std::string texttoconvert) {
      return std::stof(texttoconvert);
    }
    
    struct Test {
      template<EType type>
      decltype(auto) SomeMethod(std::string texttoconvert) {
        return convert<type>(texttoconvert);
      }
    };
    
    int main() {
      Test t;
      float f = t.SomeMethod<eFloat>("3.14");
      std::cout << f << "\n";
    }
    

    live example.