tags:

views:

62

answers:

3

I'm using Visual Studio 2008. I have this class:

template <bool T1>
class Foo {
public:
    void doSomething() {}

    Foo<T1>& operator=(int a) {
        doSomething();
        return *this;
    }
};

But I want that the method operator= be hidden (by simply doing: return *this) if the template parameter T1 is false.

I need that for instances of Foo, the lines:

Foo<false> foo;
foo = 20; //this should give a compilation error

So I tried specializing the class definition:

template<>
class Foo<false> {
private:
    Foo<false>& operator=(int a) {
        return *this;
    }
};

However, by doing this I lose the method doSomething() on instances that are Foo<false>, which is not what I need.

I've tried removing the operator= with boost::enable_if, like this:

typename boost::enable_if<
    boost::mpl::bool_<T1>
    , Foo<T1>
>::type&
operator=(int a) {
    callProxy();
    return *this;
}

But that makes me unable to have a class like the following:

class Bar {
public:
   Foo<true> assignable;
   Foo<false> unassignable;
};

I've also tried putting both methods in Foo and removing them with boost::enable_if and boost::disable_if, like this:

 template <bool T1>
 class Foo {
 public:
    void doSomething() {}

    typename boost::enable_if<
        boost::mpl::bool_<T1>
        , Foo<T1>
    >::type&
    operator=(int a) {
        doSomething();
        return *this;
    }

 private:
    typename boost::disable_if<
        boost::mpl::bool_<T1>
        , Foo<T1>
    >::type&
    operator=(int a) {
        return *this;
    }
 };

Which didn't work too (I expected that, but it was worth trying).

So, is it possible to get the behaviour I need, and if it is, how could I do it?

+4  A: 

why not just use a regular if()?

if(T1) doSomething();

Pavel Radzivilovsky
That would work, but I need that for instances of Foo<false> calls for operator= give me a compilation error.
Edison Gustavo Muenz
@Edison: So...then your code `class Bar { public: Foo<true> assignable; Foo<false> unassignable; };` **shouldn't** work.
GMan
Ok, then just add static int dummy[T1]; in the body of the operator=When T1 is false, the array size will be zero, which is not allowed. Or you could use BOOST_STATIC_ASSERT.
zvrba
Why not? I can provide a no-op operator=, like i did when specializing Foo with:template <> class Foo<false> { private: Foo<false> } };
Edison Gustavo Muenz
@Edison: So, do you want a compile-error or a no-op operator? You must make up your mind.
GMan
+1  A: 

Instead of special-casing the false case, you could special-case the true case, and only include the operator= in that case.

TreDubZedd
If I do that, the following code won't compile: class Bar { public: Foo<true> assignable; Foo<false> unassignable; };
Edison Gustavo Muenz
+1  A: 

You can statically assert the condition:

Foo<T1>& operator=(int a) {
    BOOST_STATIC_ASSERT(T1);
    doSomething();
    return *this;
}
Georg Fritzsche
That worked as a charm. Thank you very much.
Edison Gustavo Muenz