Reputation: 51505
Suppose:
struct P {
P(int v);
};
int v;
P p = 0; // allow
P q = v; // Fail at compile time
How can achieve that? any template trick?
I am trying to write allocator which has special pointer properties. unfortunately std implementation uses implicit conversion from int to NULL pointer:
{ return __n != 0 ? _M_impl.allocate(__n) : 0; }
my pointer implementation: http://code.google.com/p/asadchev/source/browse/trunk/projects/boost/cuda/mapped_ptr.hpp
my allocator implementation: http://code.google.com/p/asadchev/source/browse/trunk/projects/boost/cuda/allocator.hpp
I want to enforce explicit construction using raw pointer to avoid nasty problems.
Upvotes: 1
Views: 200
Reputation: 68240
What about:
struct P {
P(int v) { assert(v == 0); }
};
Some compilers might even see it already at compile time if you wrongly use this.
Upvotes: 0
Reputation: 507105
You can do it but you won't like it
struct P {
private:
struct null_absorb;
public:
P(null_absorb *v);
};
int v;
P p = 0; // allow
P q = v; // Fail at compile time
This will only allow null pointer constants. In other words, zero compile time values.
Upvotes: 6
Reputation: 35188
Do you really want to allow implicit conversions from int
? That could open up a host of unintended coding errors. Since it's really a coding error to pass anything other than 0, you could do one of these:
#include <cassert>
struct P
{
// Option #1, only allow 0 as an argument.
explicit P(int v)
{
assert(v == 0);
// other stuff goes here.
}
// Option #2, provide a no-argument constructor.
P()
{
// behave like P(0)
}
};
Upvotes: 2
Reputation: 3076
C++ 's static assert might do the trick: http://www.skynet.ie/~caolan/Fragments/C++StaticAssert.html
I think it is from newer C++ however.
Also, what about just initializing it to zero at compile time. Maybe making it constant.
Upvotes: 0
Reputation: 15263
I don't think there's any direct way to distinguish between a literal and a variable like you want. One alternative is to require the constructor to accept a reference to an integer: This would work with a variable, but not with a literal.
Upvotes: 1
Reputation: 272657
I don't know why you'd want to do it, but something like:
struct P
{
protected:
P(int v) {}
public:
template <int N>
static P create() { return P(N); }
};
int main()
{
P p = P::create<0>();
}
Upvotes: 3