用鸭子在C ++中输入的模板

时间:2012-06-29 23:53:48

标签: c++ templates duck-typing

有没有办法要求模板类型具有属性?

例如:

template <typename T, typename U>
void foo()
{
    U a,b;
    bool truthiness = T()(a,b);
    if (truthiness)
        // do something
}

那么,我如何要求T定义operator()(U a, U b),返回特定类型?这可能吗? (我知道它在d中,但我不确定c ++)。

PS。如果鸭子打字错了,请告诉我,我相信这是正确的,但我不确定。

3 个答案:

答案 0 :(得分:4)

考虑到你的意图,你的语法错了。由于T是一种类型,T(1, 2)将使用双参数构造函数构造类型为T的临时对象。如果您想致电T s运营商(),您必须提供类似

的内容
T()(1, 2);

假设为您的目的通过临时工作打电话。

如果T没有这样的运算符(),则代码将无法编译。我实际上说模板代码的一大好处是只要语法有效(即你正在讨论的非常类型)它就“有效”,即不需要通过要求{进一步限制它来进一步限制它。 {1}}在场。

当然,在我的例子中它实际上可能有意义,因为对于operator (),代码在语法上是有效的,但是会导致通过空指针进行函数调用。但同样,这是我的代码版本所特有的,我不知道您希望将运算符T = void (*)(int, int)应用于T类型的具体对象。

话虽如此,Boost库有一些功能可以让我们检查这些属性并将它们用于模板元编程和/或静态断言中的分支,这一点毫无价值。

答案 1 :(得分:2)

通过简单表达模板,您需要T才能拥有operator()(int, int)。如果没有,它将无法编译。

但是,如果您正在创建API并希望通知用户API已经以不兼容的类型传递,那么您需要创建一个检测操作符的类型特征,并且您可以专门化该函数来区分该事实并创建一个static_assert来表明事实。

答案 2 :(得分:0)

如果您可以访问decltype,则可以相对轻松地进行自己的检查。

template <class T, class U> class check_same_type_t;

template <class T> class check_same_type_t<T, T> { };

template <class T, class U>
void foo()
{
    U a,b;
    check_same_type_t<bool, decltype(T()(a, b))> check;
    bool truthiness = T()(a,b);
    if (truthiness) ;
        // do something
}

通过以下方式实现:

struct A {
    bool operator()(int, int) { return true; }
};

struct B {
    int operator()(int, int) { return 1; }
};

int
main()
{
    foo<A, int>(); // will compile
    foo<B, int>(); // won't compile

}

请确保这是您真正想要的。 强制通用算法使用特定类型可能会让您感到厌烦。如果某个类型可以隐式转换为bool,为什么在您的条件下使用它会不合理?