Templates accepting “anything” in C++

后端 未结 4 791
[愿得一人]
[愿得一人] 2021-01-12 05:53

I have a simple template struct associating a string with a value

template struct Field
{
    std::string name; T self;
}

4条回答
  •  星月不相逢
    2021-01-12 06:18

    Java generics are closer to just stuffing a boost::any into the self variable than to C++ templates. Give that a try. C++ templates create types that have no runtime or dynamic relarionship to each other by default.

    You can introduce such a relationship manually, say via a common parent and type erasure and judicious use of pImpl and smart pointers.

    C type variardic arguments are out of style in C++11. Variardic template arguments are very type safe, so long as your compiler has support for them (Nov 2012 CTP for MSVC 2012 has support for them (not update 1, the CTP), as does clang, and non-ancient versions of gcc).

    Templates in C++ is a kind of metaprogramming, closer to writing a program that writes a program than it is to Java Generics. A Java Generic has one shared "binary" implementation, while each instance of a C++ template is a completely different "program" (which, via procedures like COMDAT folding, can be reduced to one binary implementation), whose details are described by the template code.

     template
     struct Field {
       T data;
     };
    

    is a little program that says "here is how to create Field types". When you pass in an int and double, the compiler does something roughly like this:

     struct Field__int__ {
       int data;
     };
     struct Field__double__ {
       double data;
     };
    

    and you wouldn't expect these two types to be convertible between.

    Java generics, on the other hand, create something like this:

    struct Field {
      boost::any __data__;
      template
      T __get_data() {
        __data__.get();
      }
      template
      void __set_data(T& t) {
        __data__.set(t);
      }
      property data; // reading uses __get_data(), writing uses __set_data()
    };
    

    where boost::any is a container that can hold an instance of any type, and access to the data field redirects through those accessors.

    C++ provides means to write something equivalent to Java generics using template metaprogramming. To write something like C++ templates in Java, you'd have to have your Java program output custom Java byte or source code, then run that code in a way that allows a debugger to connect back to the code that writes the code as the source of the bugs.

提交回复
热议问题