我构建了以下MCVE来说明我使用g ++ 4.7时遇到的问题。它通过decltype()
使用SFINAE来确定是否可以使用给定的参数类型调用仿函数类型(专门用于测试在参数类型为void
时是否可以在没有参数的情况下调用仿函数类型)。 / p>
#include <iostream>
#include <utility>
template <typename F, typename A>
class can_call_functor_impl
{
private:
typedef char yes[1];
typedef char no[2];
template <typename U>
static auto test(U *)
-> decltype(void(std::declval<U const &>()(std::declval<A &>())),
std::declval<yes &>());
template <typename>
static no & test(...);
public:
static constexpr bool value = sizeof(test<F>(0)) == sizeof(yes);
};
template <typename F>
class can_call_functor_impl<F, void>
{
private:
typedef char yes[1];
typedef char no[2];
template <typename U>
static auto test(U *)
-> decltype(void(std::declval<U const &>()()),
std::declval<yes &>());
template <typename>
static no & test(...);
public:
static constexpr bool value = sizeof(test<F>(0)) == sizeof(yes);
};
template <typename F, typename A>
class can_call_functor :
public std::integral_constant<bool, can_call_functor_impl<F, A>::value> {};
class int_functor
{
public:
void operator()(int) const;
};
#define PRINT_EXP(e) (std::cout << #e " == " << (e) << std::endl)
int main(void) {
PRINT_EXP((can_call_functor<int_functor, int>::value));
PRINT_EXP((can_call_functor<int_functor, short>::value));
PRINT_EXP((can_call_functor<int_functor, void>::value));
PRINT_EXP((can_call_functor<int_functor, double>::value));
PRINT_EXP((can_call_functor<int_functor, int_functor>::value));
}
g ++上的输出(Debian 4.7.2-5)4.7.2:
(can_call_functor<int_functor, int>::value) == 1
(can_call_functor<int_functor, short>::value) == 1
(can_call_functor<int_functor, void>::value) == 1
(can_call_functor<int_functor, double>::value) == 1
(can_call_functor<int_functor, int_functor>::value) == 1
这个输出令人不安,因为我预计第三行和第五行的结果为0,实际上later g++ and clang一致认为应该是这种情况。
对于我能提出的任何can_call_functor<int_functor, T>::value
,g ++ 4.7似乎评估T
为真。
我强烈怀疑这是一个特定于4.7的g ++错误,但我找不到任何证据(这些问题特别难以在bug跟踪器上搜索),所以我正在寻找明确的答案:
这是一个g ++ 4.7错误,如果有的话有解决方法吗?如果它不是g ++中的错误那么我的代码中的错误在哪里?
答案 0 :(得分:1)
这是一个g ++ 4.7错误吗?
似乎是
on 4.9.1它产生了
(can_call_functor<int_functor, int>::value) == 1
(can_call_functor<int_functor, short>::value) == 1
(can_call_functor<int_functor, void>::value) == 0
(can_call_functor<int_functor, double>::value) == 1
(can_call_functor<int_functor, int_functor>::value) == 0
但是我找不到任何证据(这些问题特别难以在bug追踪器上搜索)
这个可能是错误https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53788
如果有,是否有解决方法?
...嗯
我想不出任何好的
移至至少4.8?你可以并排安装几个gcc