how to overcome VS lack of 'export' keyword

D

David Carricajo

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
 
A

Alf P. Steinbach

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
 
D

David Carricajo

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.

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.



No; see the FAQ.



This doesn't make sense as valid code.


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 said:
In that case you need to provide a parenthesis with actual arguments.


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


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.


Try overloading.


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
 
D

David Carricajo

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
 
T

tonydee

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,736
Latest member
AdolphBig6

Latest Threads

Top