C ++将隐式构造限制为特定值

时间:2010-09-27 21:20:31

标签: c++ templates constructor

假设:

struct P {
    P(int v);
};

int v;
P p = 0; // allow
P q = v; // Fail at compile time

怎么能实现呢?任何模板技巧?

我正在尝试编写具有特殊指针属性的allocator。不幸的是,std实现使用从int到NULL指针的隐式转换:

{ return __n != 0 ? _M_impl.allocate(__n) : 0; }

我的指针实现: http://code.google.com/p/asadchev/source/browse/trunk/projects/boost/cuda/mapped_ptr.hpp

我的分配器实现: http://code.google.com/p/asadchev/source/browse/trunk/projects/boost/cuda/allocator.hpp

我想使用原始指针强制显式构造,以避免讨厌的问题。

6 个答案:

答案 0 :(得分:6)

你可以做但你不喜欢它

struct P {
private:
    struct null_absorb;

public:
    P(null_absorb *v);
};

int v;
P p = 0; // allow
P q = v; // Fail at compile time

这将只允许空指针常量。换句话说,零编译时间值。

答案 1 :(得分:3)

我不知道你为什么要这样做,但有点像:

struct P
{
protected:
    P(int v) {}

public:
    template <int N>
    static P create() { return P(N); }

};

int main()
{
    P p = P::create<0>();
}

答案 2 :(得分:2)

您真的想要允许来自int的隐式转换吗?这可能会导致许多意外的编码错误。因为传递0以外的任何东西确实是一个编码错误,所以你可以做其中的一个:

#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)
    }
};

答案 3 :(得分:1)

我认为没有任何直接的方法来区分你想要的文字和变量。另一种方法是要求构造函数接受对整数的引用:这可以使用变量,但不能使用文字。

答案 4 :(得分:0)

C ++的静态断言可能会起到作用:http://www.skynet.ie/~caolan/Fragments/C++StaticAssert.html

我认为它来自较新的C ++。

另外,如何在编译时将其初始化为零。也许让它保持不变。

答案 5 :(得分:0)

怎么样:

struct P {
    P(int v) { assert(v == 0); }
};

如果您错误地使用它,某些编译器甚至可能已经在编译时看到它。