views:

103

answers:

2

I'm writing a smart ptr template which is intended to be instantiated only for a given base class and its subclasses, which provides boost::shared_ptr-like implicit conversions to variants MyPtr<U> of the template MyPtr<T> has long as the conversion is valid from T* to U* (valid base class and const-compatible).

This was working fine in vs2005, but not with g++ on linux so my colleague changed it there, but doing so it broke the const-correctness.

My problem is that I want to unit test that some conversions are not valid (assign MyPtr<const T> to MyPtr<T> for example), resulting in the file not compiling! But you can't have a file not compiling in the solution...

If there some VS-specific #pragma or some SFINAE trick that could test a given construct is NOT valid and therefore doesn't compile?

Thanks, --DD

+1  A: 

You could run the command line compiler, cl, which is pretty easy to set up, and capture its error message output.

No makefile, and hardly any info from the solution/project. Just the include path and a source file. At it's simplest you just need a program that "reverses" the exit code of another program:

#include <sstream>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    std::ostringstream command;

    for (int n = 1; n < argc; n++)
        command << argv[n] << " ";

    return (system(command.str().c_str()) == EXIT_SUCCESS)
                ? EXIT_FAILURE : EXIT_SUCCESS;
}

It simply reconstitutes the arguments passed to it into (omitting its own name) and exits the resulting command line, and then returns success if it fails and failure if it succeeds. That is enough to fool Visual Studio or make.

Technically the reconstituted command line should quote the arguments, but that will only be necessary if you are insane enough to put spaces in your build directory or source file names!

Daniel Earwicker
I'm looking for something that runs within visual studio, which would be no different than RMB my unit test project in the solution, selecting "Set As Startup Project" and press F5. Having external scripts / makefiles that would duplicate all the build info from the solution isn't really the kind of solution I have in mind, and the reporting in case of failure would likely be external too.
ddevienne
You seem to be imagining this will be harder than it really is! See updated answer. It's really simple (much simpler than writing a smart pointer).
Daniel Earwicker
I'd rather write smart ptr code (well, actually I'd rather use the Boost ones, but this is a special case here, which in fact uses a shared_ptr inside) rather try to write a cross-platform compiler-forking, output-parsing, program that can work with VS and GCC/make ;-)
ddevienne
That's way overboard. The output is merely the exit code. This is a completely trivial problem as far as I can see. I've updated the answer with the necessary code.
Daniel Earwicker
A: 

If a given argument (in your case 'const T') would satisfy all the other unit tests except this one you're looking for, isn't it the sign that it would be a perfectly acceptable case? In other words, if it works, why forbid it?

Xavier Nodet
Uh. no ;-) If you have a boost::shared_ptr<const std::string>, you can't implicitly convert it to boost::shared_ptr<std::string>, for the same reasons C++ forbids the same conversion on raw pointers. My situation is the similar, albeit more complex because my smart pointer needs to use boost::mpl to decide which T goes into the shared_ptr (thus the bug, mpl isn't super easy).
ddevienne