检查编译时的类构造函数签名

Kon*_*tin 8 c++ boost

有没有办法在编译时检查某些类是否具有某些参数的构造函数??

例如:

class foo {
    foo(std::string &s) {
    }
};
Run Code Online (Sandbox Code Playgroud)

我想在编译时检查构造函数与std :: string并始终定义.也许boost提供了这样的功能?

MSa*_*ers 7

检查特定函数是否存在的常用方法是获取其地址并将其分配给虚拟变量.这比目前提到的测试要精确得多,因为这会验证确切的函数签名.问题是string&签名中的具体问题,因此非常规,因此可能会修改字符串.

但是,在这种情况下,您不能使用take-the-address-and-assign-it技巧:构造函数没有地址.那么,你如何检查签名呢?简单地说:在虚拟课堂上与它交朋友.

template<typename T>
class checkSignature_StringRef {
    friend T::T(string&);
};
Run Code Online (Sandbox Code Playgroud)

这也是一个非常具体的检查:它甚至不会匹配类似的构造函数foo::foo(std::string &s, int dummy = 0).


小智 5

我想出了一个类似的问题,希望在参数兼容时将构造函数转发到基类,而在不兼容时做其他事情。

这是一个适用于 MSVC 2013 的通用特征(需要 C++11 的东西):

namespace detail {
    template<class type,class...Args>
    class constructible_from
    {
        template<class C>
        static C arg();

        template <typename U>
        static boost::mpl::true_ constructible_test(U *, decltype( U(arg<Args>()...) ) * = 0 );
        static boost::mpl::false_ constructible_test(...);

    public:

        typedef decltype( constructible_test(static_cast<type*>(nullptr)) ) result;

    };
}   // namespace detail

template<class type>
struct constructible
{
    template<class...Args>
    struct from :
        detail::constructible_from<type,Args...>::result {};
};
Run Code Online (Sandbox Code Playgroud)

这是一个特征使用示例,我将enable_if应用程序留作练习:D:

struct b{};
struct c{};
struct d : c{};

struct a
{
    a() {}
    a(a &) {}
    a(b,c) {}
    a(c) {}
};


static_assert(
    constructible<a>::from<>::value,
    "a()"
);
static_assert(
    constructible<a>::from<a&>::value,
    "a(a&)"
);
static_assert(
    ! constructible<a>::from<const a&>::value,
    "a(const a&)"
);
static_assert(
    constructible<a>::from<b,c>::value,
    "a(b,c)"
);
static_assert(
    ! constructible<a>::from<b>::value,
    "a(b)"
);
static_assert(
    constructible<a>::from<c>::value,
    "a(c)"
);
static_assert(
    constructible<a>::from<d>::value,
    "a(d)"
);
Run Code Online (Sandbox Code Playgroud)


Igo*_*kon 3

如果你确实需要,可以添加这个功能:

static void _dummy() { std::string s; foo f(s); }
Run Code Online (Sandbox Code Playgroud)

如果没有你的构造函数,编译将会失败。注意:您的构造函数是私有的。如果是故意的,那么 _dummy 应该位于类内部。否则,你可以在课外进行。

另外,如果您的代码中经常发生这种情况,您可以将其模板化,甚至将其设为宏。

但说实话,它看起来仍然像一个黑客。你确定你需要它吗?