c++11 - 使用 GCC 在继承的模板静态成员函数上使用 decltype

标签 c++11 inheritance static-methods decltype gcc4.9

我在 coliru.stacked-crooked.com 上提供了以下工作代码.

作为static std::false_type check(...)是重复的,我想知道我们是否可以分解它。例如在基类中。正如 Jonathan Wakely 指出的那样我在问题底部的尝试使用 Clang 进行编译,但不使用 GCC。

我尝试了很多可能性,但似乎无法使用 decltype关于使用 GCC 继承的模板静态函数。

问题:
1. GCC-4.9在这一点上是否符合C++11标准?
2. 使用符合 GCC 的解决方法是什么 decltype关于继承的模板静态成员函数?

#include <type_traits>
#include <iostream>
#include <string>

template<typename T>
struct is_addable
{
  template<typename U> static std::false_type check(...);
  template<typename U> static auto            check(int) 
       -> decltype( std::declval<U>() + std::declval<U>(), std::true_type{});
  using type = decltype(check<T>(0));
};

template<typename T>
struct is_multiplicable
{
  template<typename U> static std::false_type check(...);
  template<typename U> static auto            check(int)
    -> decltype( std::declval<U>() * std::declval<U>(), std::true_type{});
  using type = decltype(check<T>(0));
};

int main()
{
  std::cout <<"is_addable\n";
  std::cout <<" long:   "<< is_addable<long>::type::value        <<'\n';
  std::cout <<" string: "<< is_addable<std::string>::type::value <<'\n';
  std::cout <<" void:   "<< is_addable<void>::type::value        <<'\n';

  std::cout <<"is_multiplicable\n";
  std::cout <<" long:   "<< is_multiplicable<long>::type::value        <<'\n';
  std::cout <<" string: "<< is_multiplicable<std::string>::type::value <<'\n';
  std::cout <<" void:   "<< is_multiplicable<void>::type::value        <<'\n';
}

我的一个尝试

编辑: 添加了 template<typename U>正如 Jonathan Wakely 指出的那样

struct default_check
{ 
  template<typename U>
  static std::false_type check(...);
};

template<typename T>
struct is_addable : default_check
{
  using default_check::check;

  template<typename U> static auto check(int) 
       -> decltype( std::declval<U>() + std::declval<U>(), std::true_type{});

  using type = decltype(check<T>(0));
};

GCC-4.9.2 在 coliru.stacked-crooked.com 上失败

> g++ -std=c++11 -Wall -pedantic -Wextra -Wfatal-errors main.cpp
main.cpp: In instantiation of 'struct is_addable<void>':
main.cpp:38:63:   required from here
main.cpp:19:30: error: no matching function for call to 'is_addable<void>::check(int)'
   using type = decltype(check<T>(0));
                              ^
compilation terminated due to -Wfatal-errors.

Clang-3.4.1 在 godbolt.org 上成功

> clang++ -std=c++11 -Wall -pedantic -Wextra -Wfatal-errors

最佳答案

你的 default_check::check不是模板,所以你不能像check<T>(0)那样调用它

解决方案很简单,就是让它成为一个函数模板:

struct default_check
{
  template<typename T>  // <-- ADD THIS LINE
    static std::false_type check(...);
};

Clang 接受了,但是 GCC 仍然不会编译它(不知道为什么)所以我就放弃了 default_check然后写check在您需要的任何地方,就像您最初拥有的那样。反正更清楚了。

关于c++11 - 使用 GCC 在继承的模板静态成员函数上使用 decltype,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29013260/

相关文章:

c++ - gcc 的 std::bind 在哪里将参数复制到数据结构中?

python - Mixin 覆盖继承的方法

来自非成员函数的 C++ 虚拟继承

Objective-C if ([self isKindOfClass : . .. ]) 静态方法

java - JButton 仅在可见性设置为 True-Java 时才起作用

json - boost::ptree 找到了吗?或者如何访问深层数组? C++

c++ - 使用 unique_ptr 和自定义删除器包装 C 代码

C++ 虚拟继承 - 虚函数 ""的覆盖不明确

javascript - 我什么时候想在 JavaScript 中使用 “class”(静态)方法或属性?

c++ - 计算两个数的超表中的第 N 个数