gpt4 book ai didi

templates - 运算符重载的模板化定义

转载 作者:行者123 更新时间:2023-12-01 10:49:29 25 4
gpt4 key购买 nike

我有一些函数对象,每个函数对象都定义了 operator() 的各种双参数重载:

class Foo {};
class Bar {};

struct Functor1 {
double operator()(const Foo &, const Bar &) { return 2.2; }
double operator()(const Bar &, const Foo &) { return 3.1; }
};

struct Functor2 {
int operator()(const Foo &, const Foo &) { return 2; }
int operator()(const Bar &, const Bar &) { return 3; }
};

现在我想做的是编写一个实用程序,让我可以将这些仿函数一个一个地附加到一个二元运算符上。这是我的尝试:

#define ATTACH_FUNCTOR_TO_OPERATOR(OPERATOR, FUNCTOR) \
template<typename Operand1, typename Operand2> \
decltype(FUNCTOR(std::declval<Operand1>(), std::declval<Operand2>())) \
operator OPERATOR(const Operand1 &operand1, const Operand2 &operand2) { \
return FUNCTOR(operand1, operand2); \
}

第一次运行正常:

ATTACH_FUNCTOR_TO_OPERATOR(+, Functor1());

但是当我使用相同的运算符添加第二次调用时:

ATTACH_FUNCTOR_TO_OPERATOR(+, Functor2());

然后 Visual Studio 2013 告诉我“函数模板已经定义”。

请注意,对于任何一对操作数,只有一个 + 的实例,其返回类型为 decltype(FUNCTOR(std::declval<Operand1>(), std::declval<Operand2>()))可以解析为任何特定类型。我希望任何其他尝试的实例化都会悄无声息地失败并且不会造成任何麻烦——也就是 SFINAE。

我也尝试过各种风格的enable_if , 没有成功。

在标准 C++11 中是否有合法的方法来执行此操作?

有没有在 VS2013 中工作的方法?

最佳答案

这是一个 known bug在 VC++ 中。我们可以将其简化为以下自包含示例:

template<typename T> void f(decltype(T::a)) {}
template<typename T> void f(decltype(T::b)) {}

source_file.cpp(2) : error C2995: 'void f(unknown-type)' : function template has already been defined source_file.cpp(1) : see declaration of 'f'

问题似乎是 VC++ 认为“未知类型”类型(即来自 decltype 的类型)是等价的,目的是确定函数模板是否定义是重新定义。

一种解决方法是使用唯一的、未使用的类型来消除模板的歧义:

#define ATTACH_FUNCTOR_TO_OPERATOR(OPERATOR, FUNCTOR) \
template<typename Operand1, typename Operand2> \
typename std::conditional<true, \
decltype(FUNCTOR(std::declval<Operand1>(), std::declval<Operand2>())), \
std::integral_constant<int, __LINE__>>::type \
operator OPERATOR(const Operand1 & operand1, const Operand2 &operand2) { \
return FUNCTOR(operand1, operand2); \
}

关于templates - 运算符重载的模板化定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22040500/

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