简体   繁体   中英

C++ templates specialization for signature template class

I am creating signature template class. I am facing a problem for " void " return type. Here is my solution to handle void return type, which is I create a template specialization class for it.

template<typename TSignature>
class CAction;

template<typename TRetType, typename... Args>
class CAction<TRetType(Args...)> {
public:

    TRetType func(Args... a)
    {
        cout << "non void" << endl;
        myPrint(a...);
        cout <<"\n\n";
        TRetType nRet(0);
        return nRet;
    }
};

template<typename... Args>
class CAction<void(Args...)> {
public:
    void func(Args... a)
    {
        cout << "void" << endl;
        myPrint(a...);
        cout << "\n\n";
    }
};

Below is how I initialize the class.

CAction< void(int a, int b, double c, std::string d)> on_action1;
on_action1.func(1, 2, 10.0, "a love b");

CAction< double(int a, int b, double c, std::string d)> on_action2;
on_action2.func(1, 2, 10.0, "a love b");

The code above work correctly. I am just curious, besides above method, is there any better solution ? For example : May I create a template specialization member function ( func ) to handle " void " return type ? Please show me code example if you know more details, thank you very much.

If you have access to C++17 you can throw in an if constexpr and return the appropriate values in each branch:

TRetType func(Args... a) {
  if constexpr(!std::is_void<TRetType>{}) {
      cout << "non void" << endl;
      TRetType nRet(0);
      return nRet;
    }
  else {
    cout << "void" << endl;
  }
}

Otherwise you can use a tag-dispatching technique to overload based on the return type. Since specializing cannot be done with non-template functions:

template<class T>
struct type {};

TRetType func(type<TRetType>, long, Args... a) {
  cout << "non void" << endl;
  TRetType nRet(0);
  return nRet;
}

void func(type<void>, int, Args... a) {
  cout << "void" << endl;
}

TRetType func(Args... a) {
  return func(type<TRetType>{}, 0, a...);
}

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