K-b*_*llo 35 c++ templates sfinae constexpr c++11
我正在努力升级一些C++代码以利用C++ 11中的新功能.我有一个特性类,其中有一些函数返回基本类型,这些函数大部分时间(但并不总是)返回一个常量表达式.我想根据功能是否做不同的事情constexpr
.我提出了以下方法:
template<typename Trait>
struct test
{
template<int Value = Trait::f()>
static std::true_type do_call(int){ return std::true_type(); }
static std::false_type do_call(...){ return std::false_type(); }
static bool call(){ return do_call(0); }
};
struct trait
{
static int f(){ return 15; }
};
struct ctrait
{
static constexpr int f(){ return 20; }
};
int main()
{
std::cout << "regular: " << test<trait>::call() << std::endl;
std::cout << "constexpr: " << test<ctrait>::call() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
额外的int
/ ...
参数是这样的,如果两个函数在SFINAE之后可用,则第一个函数通过重载分辨率来选择.
使用Clang 3.2编译和运行它显示:
regular: 0
constexpr: 1
Run Code Online (Sandbox Code Playgroud)
所以这似乎有效,但我想知道代码是否合法C++ 11.特别是因为我的理解是SFINAE的规则已经改变了.
Xeo*_*Xeo 14
注意: 我在这里打开了一个关于OP代码是否实际有效的问题.我在下面重写的例子无论如何都适用.
但我想知道代码是否合法C++ 11
虽然默认模板参数可能被认为有点不寻常.我个人更喜欢以下风格,这类似于你(读:我)写一个特征来检查函数的存在,只是使用非类型模板参数并省略decltype
:
#include <type_traits>
namespace detail{
template<int> struct sfinae_true : std::true_type{};
template<class T>
sfinae_true<(T::f(), 0)> check(int);
template<class>
std::false_type check(...);
} // detail::
template<class T>
struct has_constexpr_f : decltype(detail::check<T>(0)){};
Run Code Online (Sandbox Code Playgroud)
解释时间〜
您的原始代码有效†因为默认模板参数的实例化点是其功能模板的实例化点,在您的情况下,在其中main
,因此它不能在此之前替换.
§14.6.4.1 [temp.point] p2
如果以一种使用该函数模板的默认参数定义的方式调用函数模板[...],则默认参数的实例化点是函数模板的实例化点[ ...].
在那之后,这通常是SFINAE规则.
†至少我认为如此,标准中并不完全清楚.
归档时间: |
|
查看次数: |
3983 次 |
最近记录: |