0

I have two template classes and normally I would prefer the foo version of the Search class. But sadly my compiler can not understand the foo version because of the missing c++11 support. (He will not understand this line: template <typename U = _Format>)

The bar version will create an instance of the _Format type to call the right delegate. So also a constructor is called! Would this be a performance issue compared to the Foo version? (I know this would be this is like premature optimization, but I'm interested)

#include <iostream>

struct format1 {
    format1(void) { }
};

struct format2 {
    format2(void) { }
};

namespace foo
{
    template <typename _Format>
    class Search
    {
    public:
        void createData()
        {
            doCreateData();
        }

    private:
        template <typename U = _Format>
        void doCreateData();

        template <>
        void doCreateData<format1>()
        {
            using namespace std;
            cout << "Format1" << endl;
        }

        template <>
        void doCreateData<format2>()
        {
            using namespace std;
            cout << "Format2" << endl;
        }
    };
}

namespace bar
{
    template <typename _Format>
    class Search
    {
        public:
            void createData(void)
            {
                doCreateData(_Format());
            }

        private:
            void doCreateData(format1)
            {
                using namespace std;
                cout << "Format1" << endl;
            }

            void doCreateData(format2)
            {
                using namespace std;
                cout << "Format2" << endl;
            }
    };
}

int main(int argc, char *argv[])
{
    (void)argc; (void)argv;

    bar::Search<format2> search;
    search.createData();
}
Jonas
  • 6,915
  • 8
  • 35
  • 53
Christian
  • 73
  • 6
  • 2
    `foo::Search` fails to compile not because your compiler is too old, but because it is invalid C++, see http://stackoverflow.com/a/5513109/3601321 – Corristo Mar 01 '17 at 10:20
  • It is true that `bar::Search::createData` theoretically creates a temporary. But modern compilers are able to detect that the constructor of your struct doesn't modify global state - provided the definition of the constructor is available and not too complex - and the argument is unused in the `doCreateData` function, so with enabled optimizations that construction will be elided. You can see the constructor call [here](https://godbolt.org/g/DtUQqo) on line 28 with disabled optimizations. If you change `-O0` to `-O1` the call will no longer be present. – Corristo Mar 01 '17 at 10:29
  • Besides that: What are you really trying to accomplish here? The `bar` version confuses me. What is the point of the `Search` class? Why can't you just create a function template `template void doCreateData();` with specializations `template <> void doCreateData() { std::cout << "Format1\n"; }` and `template<> void doCreateData() { std::cout << Format2\n"; }`? – Corristo Mar 01 '17 at 10:40
  • @Corristo Because it's only a sample class, in my real class i building a complex data structure and need access to class members/functions. – Christian Mar 01 '17 at 11:27
  • The important question is: Why does the `doCreateData` function have to be templated or overloaded? In both `foo::Search` and `bar::Search` you only ever call the version for the type which was passed to the `Search` template. You could also ask it the other way around: Why is `Search` templated, when you have functions for all possible types anyway? – Corristo Mar 01 '17 at 11:34
  • 1
    `_Format` is not a valid identifier in C++ programs. Identifiers starting with an underscore and capital are reserved to the compiler and its library (as macros, keywords, etc.). – Potatoswatter Mar 01 '17 at 11:48

0 Answers0