3

I need a way to check if a templated class's type is void.

Here is my attempt:

template <typename target_type, typename start_function_type, typename end_function_type> class C_rule {

  public:
    //...
    void setIntoEffect(bool true_or_false) {
          if (true_or_false == true) {
             for (size_t i = 0; i < targets.size(); i++) {
                 if (typeid(start_function_type) != typeid(void)) {
                    start_function_type start_function_return_value = enforceOnTarget(targets.at(i));
                 }

                 else {
                    enforceOnTarget(targets.at(i));
                 }
             }
          }

          else if ((true_or_false == false) && (is_in_effect == true)) {
             for (size_t i = 0; i < targets.size(); i++) {
                 if (typeid(end_function_type) != typeid(void)) {
                    end_function_type end_function_return_value = removeFromTarget(targets.at(i));
                 }

                 else {
                    removeFromTarget(targets.at(i));
                 }
             }
          }
          is_in_effect = true_or_false;
     }

  protected:
    //...
  private:
    //...

};

However, this generates a compiler error complaining about the two variables "start_function_return_value" and "end_function_return_value" being declared void when created an object of C_rule with "start_function_type" and "end_function_type" being void. I'm trying to prevent creating a variable to store the return value from the 'start' and 'end' functions for the rule, if the return type of those functions is void (since void functions obviously do not return anything). And, as you can see, I'm trying to use the typeid operator for that purpose, but it doesn't appear to be working. Apparently, the if statement is still being entered when the start_function_type and end_function_type is void, and I don't know why. Maybe typeid doesn't work with void? I googled the question, but couldn't find an answer, so that's why I'm asking it here.

Thanks in advance.

Jammanuser
  • 61
  • 1
  • 4
  • Perhaps this helps? http://stackoverflow.com/questions/9625526/check-at-compile-time-if-template-argument-is-void – chris Mar 02 '13 at 15:30
  • How about `std::is_void`? – Kerrek SB Mar 02 '13 at 15:31
  • The problem is that we don't have a static if. If we did, you could do what you're trying to do now, but with `std::is_same` or `std::is_void` instead of `typeid`. – chris Mar 02 '13 at 15:33
  • Hmm..std::is_void gave me hope, but after trying it just now in those if statements, in place of the typeid expressions, the compiler gave me the following error: – Jammanuser Mar 02 '13 at 15:42
  • This file requires compiler and library support for the upcoming \ ISO C++ standard, C++0x. This support is currently experimental, and must be \ enabled with the -std=c++0x or -std=gnu++0x compiler options. – Jammanuser Mar 02 '13 at 15:43
  • @Jammanuser, The answers in my link should still help. – chris Mar 02 '13 at 16:01

1 Answers1

6

In C++11, you could use the standard std::is_same<> type trait to verify if two types are the same:

#include <type_traits>

// ...
bool same = std::is_same<T1, T2>::value;

In your case, this could become:

bool same = std::is_same<start_function_type, void>::value;

However, this would not solve your problem, because an if statement is not a compile-time (static) if: both branches of the if statement still have to compile.

What you could do is to specialize your class template for the cases where start_function_type or end_function_type is void, or to factor out the part of the code which deals with them into a separate, specialized class template.

Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
  • Hmm..my one big problem is I'm currently using C++98, I guess, and I don't know how to upgrade my compiler and IDE to use C++11 instead. Could you help with that? The IDE I'm using right now is Qt Creator and the compiler is MinGW. – Jammanuser Mar 02 '13 at 16:03
  • @Jammanuser: Well, if you will specialize your template, you do not need C++11. Just learn about template specialization. I will post some more detailed code if I will have time. – Andy Prowl Mar 02 '13 at 16:05
  • @Jammanuser, [This site](http://nuwen.net/mingw.html) is good for MinGW distros. Keep in mind that GCC 4.8.0 is coming out really soon, too. Don't forget to use `-std=c++11`. Anyway, I don't see where C++11 is needed here, though. As the answer states, you need to specialize it for as long as we don't have `static if`. – chris Mar 02 '13 at 16:05
  • Well, I'm having trouble wrapping my mind around the concept of "specializing my class template for cases where start_function_type or end_function_type is void" when the only way, it seems, to check if they're void is by using std::is_void or std::is_same which both use C++11 (or is it C++0x??..). – Jammanuser Mar 02 '13 at 16:12
  • Wait...unless you meant like by specifying a void type in the template itself, thereby forcing the type to always be void (if that even works). But that kind of defeats the whole purpose of templating, now doesn't it... – Jammanuser Mar 02 '13 at 16:14
  • @Jammanuser: Try reading a bit about class template specialization and you'll see what I mean. You do not need `std::is_void`. – Andy Prowl Mar 02 '13 at 16:14
  • Well, I just did, but it seems like the article I was reading (on cprogramming.com) was talking about specializing the general template type by doing a after the class name, which it said tells the compiler to match pointers of any type to the more general typename. But I don't see how that could help in my case, since I was wanting the start function type and end function type to be literally anything the user wanted. Specializing the type via pointers would force the start function type and end function type to be a pointer type, wouldn't it? Meaning, I couldn't use void for example. – Jammanuser Mar 02 '13 at 16:58