how to overcome VS lack of 'export' keyword

Discussion in 'C++' started by David Carricajo, Apr 26, 2010.

  1. Hi,

    For the sake of clarity i use abbreviations of my original problem,
    i'm using boost::test along with boot::units to checks operations over
    types:

    //new types
    typedef quantity<electric_potential,complex_type> tPotential;
    typedef quantity<current,complex_type> tCurrent;

    //generic operations
    template<class T>
    void BOOST_CHECK_MATRIX_EQUAL(const T t, const T v);

    template<class T>
    void BOOST_CHECK_MATRIX_EQUAL(const someArray<quantity<T> > t, const
    someArray<quantity<T> > v);

    template<>
    void BOOST_CHECK_MATRIX_EQUAL<double>(const someOtherArray<double> t,
    const someArray<double> v);


    I use both types and operations over several compilation units, thus i
    should only define templates in .cpp files, in the header files i
    declare both templates and pointers to template functions, but in
    defining pointers to template functions i lose the template argument
    lookup:

    typedef (*BOOST_CHECK_MATRIX_EQUAL_TYPE)(const someArray<tCurrent>,
    const someArray<tCurrent>);
    BOOST_CHECK_MATRIX_EQUAL_TYPE pCHECK_MATRIX = *
    BOOST_CHECK_MATRIX_EQUAL<tCurrent>;

    tSomeArray someArray<tCurrent> i1, i2;
    BOOST_CHECK_MATRIX_EQUAL_TYPE(i1, i2); //ok,

    tSomeOtherArray someOtherArray<tPotential> u1, u2;
    BOOST_CHECK_MATRIX_EQUAL_TYPE(u1, u2); //obvious error

    Since c++ lacks typedef templates and i'd like to span my code over
    several compilation units, also i find it hard to change all of my
    source code to change names of functions according to their
    parameters. I don't find any way to let compiler instantiate the
    correct function it should invoke. What would i try instead?

    Much appreciated
    David Carricajo, Apr 26, 2010
    #1
    1. Advertising

  2. On 26.04.2010 16:56, * David Carricajo:
    >
    > For the sake of clarity i use abbreviations of my original problem,
    > i'm using boost::test along with boot::units to checks operations over
    > types:
    >
    > //new types
    > typedef quantity<electric_potential,complex_type> tPotential;
    > typedef quantity<current,complex_type> tCurrent;
    >
    > //generic operations
    > template<class T>
    > void BOOST_CHECK_MATRIX_EQUAL(const T t, const T v);


    OK, there are three problems with that, all about clashing with convention:

    1. Use all uppercase names for macros only.
    - Otherwise you run into all sorts of name collision problems, and you
    confuse the knowledgable reader by indicating that the name is a macro.

    2. Don't use other libraries' prefixes, like BOOST_, for your identifiers.
    - Again, sowing confusion and possible name clashes.

    3. Don't use 'const' at top level for a routine /declaration/'s formal args.
    - It has no effect technically (the definition doesn't necessarily have
    those 'const's), but it misleads the reader into thinking the arguments
    are passed by reference, when they're actually passed by value.


    > template<class T>
    > void BOOST_CHECK_MATRIX_EQUAL(const someArray<quantity<T> > t, const
    > someArray<quantity<T> > v);


    Here, since you're passing arrays you should pass by reference unless there is
    some special reason not to. You don't want to copy all that data.


    > template<>
    > void BOOST_CHECK_MATRIX_EQUAL<double>(const someOtherArray<double> t,
    > const someArray<double> v);
    >
    >
    > I use both types and operations over several compilation units, thus i
    > should only define templates in .cpp files, in the header files i
    > declare both templates and pointers to template functions


    No; see the FAQ.


    >, but in
    > defining pointers to template functions i lose the template argument
    > lookup:
    >
    > typedef (*BOOST_CHECK_MATRIX_EQUAL_TYPE)(const someArray<tCurrent>,
    > const someArray<tCurrent>);


    This doesn't make sense as valid code.


    > BOOST_CHECK_MATRIX_EQUAL_TYPE pCHECK_MATRIX = *
    > BOOST_CHECK_MATRIX_EQUAL<tCurrent>;


    And this doesn't make sense as valid code.

    Perhaps you're trying to /call/ the matrix equality checking function.

    In that case you need to provide a parenthesis with actual arguments.



    > tSomeArray someArray<tCurrent> i1, i2;
    > BOOST_CHECK_MATRIX_EQUAL_TYPE(i1, i2); //ok,


    No it's not OK. You'd never get that past any compiler.


    > tSomeOtherArray someOtherArray<tPotential> u1, u2;
    > BOOST_CHECK_MATRIX_EQUAL_TYPE(u1, u2); //obvious error


    Sorry, since the earlier code doesn't make sense, it's not obvious what error
    you're getting here for the code that you have not shown.


    > Since c++ lacks typedef templates and i'd like to span my code over
    > several compilation units, also i find it hard to change all of my
    > source code to change names of functions according to their
    > parameters.


    Try overloading.


    > I don't find any way to let compiler instantiate the
    > correct function it should invoke. What would i try instead?


    Don't know, your code doesn't make sense (it's not syntactically correct), and
    your explanation doesn't make sense to me; sorry.


    Cheers,

    - Alf
    Alf P. Steinbach, Apr 26, 2010
    #2
    1. Advertising

  3. On 26 abr, 17:41, "Alf P. Steinbach" <> wrote:
    > On 26.04.2010 16:56, * DavidCarricajo:
    >
    >
    >
    > > For the sake of clarity i use abbreviations of my original problem,
    > > i'm using boost::test along with boot::units to checks operations over
    > > types:

    >
    > > //new types
    > > typedef quantity<electric_potential,complex_type>  tPotential;
    > > typedef quantity<current,complex_type>  tCurrent;

    >
    > > //generic operations
    > > template<class T>
    > > void BOOST_CHECK_MATRIX_EQUAL(const T t, const T v);

    >
    > OK, there are three problems with that, all about clashing with convention:
    >
    >    1. Use all uppercase names for macros only.
    >       - Otherwise you run into all sorts of name collision problems, and you
    >       confuse the knowledgable reader by indicating that the name is a macro.
    >
    >    2. Don't use other libraries' prefixes, like BOOST_, for your identifiers.
    >       - Again, sowing confusion and possible name clashes.
    >
    >    3. Don't use 'const' at top level for a routine /declaration/'s formal args.
    >       - It has no effect technically (the definition doesn't necessarily have
    >       those 'const's), but it misleads the reader into thinking the arguments
    >       are passed by reference, when they're actually passed by value.


    Since i was using boost::test for my testing process, i ended up using
    the very same namespace and so i used BOOST_CHECK_MATRIX_EQUAL to
    check for equality of any pair. I stand corrected.

    I didn't have the code handy so it what i posted didn't have to
    compile, i began to write test about some library which coped with
    some types (which represented the concept of physical units) and some
    containers (which represented the concept of matrix) thus
    BOOST_CHECK_MATRIX_EQUAL (should read boost_check_matrix_equal) is a
    function template defined in a header file with specializations for
    the different containers. A function template would match any type
    (physical unit) i'd use, the specializations would cope with every
    container i'd use. Then i splitted the file and created several
    compilation units and VS failed to compile because it found different
    definitions for boost_check_matrix_equal, then i defined the template
    specializations in a .cpp file, to access those specializations i used
    typedef pointers to function template instantiations in the header
    files, yet i can no longer use the same symbol for all of them, that
    broke my code.


    >
    > > template<class T>
    > > void BOOST_CHECK_MATRIX_EQUAL(const someArray<quantity<T>  >  t, const
    > > someArray<quantity<T>  >  v);

    >
    > Here, since you're passing arrays you should pass by reference unless there is
    > some special reason not to. You don't want to copy all that data.
    >
    > > template<>
    > > void BOOST_CHECK_MATRIX_EQUAL<double>(const someOtherArray<double>  t,
    > > const someArray<double>  v);

    >
    > > I use both types and operations over several compilation units, thus i
    > > should only define templates in .cpp files, in the header files i
    > > declare both templates and pointers to template functions

    >
    > No; see the FAQ.
    >
    > >, but in
    > > defining pointers to template functions i lose the template argument
    > > lookup:

    >
    > > typedef (*BOOST_CHECK_MATRIX_EQUAL_TYPE)(const someArray<tCurrent>,
    > > const someArray<tCurrent>);

    >
    > This doesn't make sense as valid code.
    >
    > > BOOST_CHECK_MATRIX_EQUAL_TYPE pCHECK_MATRIX = *
    > > BOOST_CHECK_MATRIX_EQUAL<tCurrent>;

    >
    > And this doesn't make sense as valid code.
    >
    > Perhaps you're trying to /call/ the matrix equality checking function.


    No, i was trying to define a pointer to a template function
    instatiation, it should read:

    boost_check_matrix_equal_type pCheckMatrix = &
    boost_check_matrix_equal<tCurrent>;

    >
    > In that case you need to provide a parenthesis with actual arguments.
    >
    > > tSomeArray someArray<tCurrent>  i1, i2;
    > > BOOST_CHECK_MATRIX_EQUAL_TYPE(i1, i2); //ok,

    >
    > No it's not OK. You'd never get that past any compiler.
    >
    > > tSomeOtherArray someOtherArray<tPotential>  u1, u2;
    > > BOOST_CHECK_MATRIX_EQUAL_TYPE(u1, u2); //obvious error

    >
    > Sorry, since the earlier code doesn't make sense, it's not obvious what error
    > you're getting here for the code that you have not shown.
    >
    > > Since c++ lacks typedef templates and i'd like to span my code over
    > > several compilation units, also i find it hard to change all of my
    > > source code to change names of functions according to their
    > > parameters.

    >
    > Try overloading.
    >
    > > I don't find any way to let compiler instantiate the
    > > correct function it should invoke. What would i try instead?

    >
    > Don't know, your code doesn't make sense (it's not syntactically correct), and
    > your explanation doesn't make sense to me; sorry.
    >
    > Cheers,
    >
    > - Alf


    Thanks for your patience
    David Carricajo, Apr 27, 2010
    #3
  4. On 27 abr, 16:30, David Carricajo <> wrote:
    > On 26 abr, 17:41, "Alf P. Steinbach" <> wrote:
    >
    >
    >
    >
    >
    > > On 26.04.2010 16:56, * DavidCarricajo:

    >
    > > > For the sake of clarity i use abbreviations of my original problem,
    > > > i'm using boost::test along with boot::units to checks operations over
    > > > types:

    >
    > > > //new types
    > > > typedef quantity<electric_potential,complex_type>  tPotential;
    > > > typedef quantity<current,complex_type>  tCurrent;

    >
    > > > //generic operations
    > > > template<class T>
    > > > void BOOST_CHECK_MATRIX_EQUAL(const T t, const T v);

    >
    > > OK, there are three problems with that, all about clashing with convention:

    >
    > >    1. Use all uppercase names for macros only.
    > >       - Otherwise you run into all sorts of name collision problems, and you
    > >       confuse the knowledgable reader by indicating that the name is a macro.

    >
    > >    2. Don't use other libraries' prefixes, like BOOST_, for your identifiers.
    > >       - Again, sowing confusion and possible name clashes.

    >
    > >    3. Don't use 'const' at top level for a routine /declaration/'s formal args.
    > >       - It has no effect technically (the definition doesn't necessarily have
    > >       those 'const's), but it misleads the reader into thinking the arguments
    > >       are passed by reference, when they're actually passed by value.

    >
    > Since i was using boost::test for my testing process, i ended up using
    > the very same namespace and so i used BOOST_CHECK_MATRIX_EQUAL to
    > check for equality of any pair. I stand corrected.
    >
    > I didn't have the code handy so it what i posted didn't have to
    > compile, i began to write test about some library which coped with
    > some types (which represented the concept of physical units) and some
    > containers (which represented the concept of matrix) thus
    > BOOST_CHECK_MATRIX_EQUAL (should read boost_check_matrix_equal) is a
    > function template defined in a header file with specializations for
    > the different containers. A function template would match any type
    > (physical unit) i'd use, the specializations would cope with every
    > container i'd use. Then i splitted the file and created several
    > compilation units and VS failed to compile because it found different
    > definitions for boost_check_matrix_equal, then i defined the template
    > specializations in a .cpp file, to access those specializations i used
    > typedef pointers to function template instantiations in the header
    > files, yet i can no longer use the same symbol for all of them, that
    > broke my code.
    >


    Well, it looks like a full function template specialization is not a
    template anymore and needs to be inlined to make the linker happy but
    i don't quite like the idea of inlining such large functions.

    Regards
    David Carricajo, Apr 27, 2010
    #4
  5. David Carricajo

    tonydee Guest

    On Apr 28, 2:30 am, David Carricajo <> wrote:
    > Well, it looks like a full function template specialization is not a
    > template anymore and needs to be inlined to make the linker happy but
    > i don't quite like the idea of inlining such large functions.


    It is up to the compiler to decide what will be inlined, and (almost?)
    all modern compilers have sensible defaults. Don't worry about
    template code being constantly inlined - it won't be, and you don't
    need to use export to avoid it.

    Don't bother trying it unless you actually encounter a real problem
    with complete code, but for the record you can manually interject to
    force out-of-line usage of specific template instantiations by simply
    placing some non-templated interfacing code in between, with the
    implementation thereof including the templated code and forwarding
    requests to it. For the specific types you do this for, you'll
    firewall the client code from implementation changes in the templated
    code. Rarely needed though.

    Cheers,
    Tony
    tonydee, Apr 28, 2010
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Guest
    Replies:
    1
    Views:
    479
    Florian Diesch
    Jun 12, 2005
  2. Terry Reedy
    Replies:
    0
    Views:
    388
    Terry Reedy
    Jun 11, 2005
  3. Mariano
    Replies:
    0
    Views:
    583
    Mariano
    Dec 2, 2006
  4. Rav
    Replies:
    10
    Views:
    696
    Richard Heathfield
    Oct 23, 2006
  5. Replies:
    3
    Views:
    428
Loading...

Share This Page