我在 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/