gpt4 book ai didi

c++ - 获取函数的地址并在编译时丢弃它 : is this valid C++?

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:08:54 25 4
gpt4 key购买 nike

我一直在寻找一种方法来将模板类型参数限制为那些实现给定签名功能的参数。我似乎已经找到了一个非常优雅的解决方案,它允许 self 记录代码和相当干净的、类似于概念的错误消息。唯一的问题是我不确定那是有效的 C++ 还是恰好在 clang 和 gcc 中工作的东西。

代码如下:

#include <type_traits>
using std::enable_if;

// let's say we want something with a "regular" operator+

class Thing
{
public:
Thing operator+(const Thing&){return Thing();} //the kind of operator we want
};

class OtherThing
{
public:
OtherThing operator+(int){return OtherThing();} // the kind of operator we don't want
};

class YetAnotherThing
{
// no operator whatsoever
};

// The questionable line. I'm taking the address of the function and
// immediately discarding it using the comma operator.
#define HAS_FUNCTION(type, ret, name, args...) (static_cast<ret (type::*)(args)>(&type::name), 1)

#define T_HAS_OPERATOR_PLUS HAS_FUNCTION(T, T, operator+, const T&)

template <typename T>
typename enable_if<T_HAS_OPERATOR_PLUS>::type foo(T)
{
T t1, t2;
t1 + t2;
}

#undef T_HAS_OPERATOR_PLUS

int main()
{
Thing t;
OtherThing ot;
YetAnotherThing yat;
foo(t);
foo(ot);
foo(yat);
}

当使用 clang 构建时,它会产生以下输出:

main.cpp:43:2: error: no matching function for call to 'foo'
foo(ot);
^~~
main.cpp:29:47: note: candidate template ignored: substitution failure [with T = OtherThing]: static_cast from 'OtherThing (OtherThing::*)(int)' to 'OtherThing (OtherThing::*)(const OtherThing &)' is not allowed
typename enable_if<T_HAS_OPERATOR_PLUS>::type foo(T)
~~~~~~~~~~~~~~~~~~~ ^
main.cpp:44:2: error: no matching function for call to 'foo'
foo(yat);
^~~
main.cpp:29:47: note: candidate template ignored: substitution failure [with T = YetAnotherThing]: no member named 'operator+' in 'YetAnotherThing'
typename enable_if<T_HAS_OPERATOR_PLUS>::type foo(T)
~~~~~~~~~~~~~~~~~~~ ^
2 errors generated.

...与通常的奥术暴风雪相比,这看起来相当不错。

所以,我的问题是:它在标准 C++14 中有效吗?毕竟我在编译时获取地址,这似乎是标准不允许的事情。

此外,由于我只是黑魔法的学徒,也许有更直接的方法来完成此任务?

无论哪种方式,我们都欢迎任何意见。提前致谢。

最佳答案

首先,boost TypeTraits 有一个实现,您可以使用它而无需自己滚动 - 参见 here .其次,您通常只希望在存在多个潜在重载并且希望从候选集中删除一些重载时使用 enable_if。如果您只是想强制 T 满足某个概念,那么使用 static_assert 会更简洁。例如:

template <typename T>
auto foo(T)
{
static_assert(boost::has_plus<T, T>::value, "T must support operator+");
// Impl...
}

关于c++ - 获取函数的地址并在编译时丢弃它 : is this valid C++?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33092169/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com