简体   繁体   中英

C++ explicit return type template specialisation

This is a follow up on this (more general) question: previous question . A partial answer to the present question is given here: partial answer to the present question .

I am interested in explicit specialisation of the return type based on the template argument. While the answer presented above provides a solution to the problem, I believe that there is a more elegant way of solving the problem using C++11/14 techniques:

template<int N> auto getOutputPort2();
template<> auto getOutputPort2<0>();
template<> auto getOutputPort2<1>();

template<>
auto getOutputPort2<0>()
{
    return std::unique_ptr<int>(new int(10));
}

template<>
auto getOutputPort2<1>()
{
    return std::unique_ptr<string>(new string("asdf"));
}

The code above compiles and works as expected using gcc 4.8.3 (with -std=c++0x flag). However, it issues the following warning:

getOutputPort2 function uses auto type specifier without trailing return type.

From my understanding this will become part of the C++14 standard. However, is there a way of implementing the functionality above in C++11? Can decltype be used here?


EDIT. Following the comments below, I would also like to ask an additional question. Is the code above valid from the perspective of the C++14 standard? If not, why not?

You can extend the idea of a helper template class, and put pretty much everything in there. It's not exactly pretty for whoever has to write the specialisations, but it's very convenient for the user, who can just call f<0> , f<1> , etc. It doesn't really need decltype , but decltype does make it quite a bit easier to write.

template <int N>
struct f_impl;

template <int N>
decltype(f_impl<N>::impl()) f()
{ return f_impl<N>::impl(); }

template <> struct f_impl<0> {
  static int impl() { return 1; }
};

template <> struct f_impl<1> {
  static const char *impl() { return " Hello, world!"; }
};

int main() {
  std::puts(f<1>() + f<0>());
}

You might be able to make it a bit more manageable with macros: instead of

template <> struct f_impl<1> {
  static const char *impl() { return " Hello, world!"; }
};

you could write something along the lines of

#define DEFINE_F(N, Result)      \
  template <> struct f_impl<N> { \
    static Result impl();        \
  };                             \
  Result f_impl<N>::impl()

DEFINE_F(1, const char *) {
  return " Hello, world!";
}

but I'm not convinced it's an improvement over just writing out f_impl (with a better name) in full.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM