首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在C++中包含鸭子类型的模板

在C++中包含鸭子类型的模板
EN

Stack Overflow用户
提问于 2012-06-30 07:53:48
回答 3查看 685关注 0票数 0

有没有一种方法可以要求模板类型具有属性?

例如:

代码语言:javascript
复制
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。如果这里的鸭子输入错误,让我知道,我相信它是正确的,但我不确定。

EN

回答 3

Stack Overflow用户

发布于 2012-06-30 08:00:59

考虑到你的意图,你的语法是错误的。因为T是一个类型,所以T(1, 2)将使用两参数构造函数构造一个T类型的临时对象。如果要调用T的运算符(),则必须使用вo,如下所示

代码语言:javascript
复制
T()(1, 2);

为了你的目的,假设一个通过临时作品的呼叫。

如果T没有这样的运算符(),代码将无法编译。实际上,我要说的是,模板代码的一个很大的好处是,只要语法是有效的(即,您正在谈论的非常鸭子类型),它就“有效”,也就是说,不需要通过要求operator ()存在来进一步限制它。

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

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

票数 4
EN

Stack Overflow用户

发布于 2012-06-30 07:55:23

通过简单地表达模板,那么您需要让T具有operator()(int, int)。如果不这样做,它将不会编译。

但是,如果您正在创建一个应用程序接口,并且想要通知该应用程序接口的用户他们传入了一个不兼容的类型,那么您需要创建一个类型特征来检测操作符,并且您可以专门化该函数来区分该事实,并创建一个static_assert来指示该事实。

票数 2
EN

Stack Overflow用户

发布于 2012-07-03 12:38:08

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

代码语言:javascript
复制
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
}

这将启用以下功能:

代码语言:javascript
复制
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,为什么在您的条件下使用它会不令人满意?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11270309

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档