为什么在没有 -DPASS 的情况下编译下面的测试用例对 sfinae 不友好
why compiling below testcase without -DPASS is not sfinae friendly
$cat test.cc
#include <type_traits>
struct foo{
};
template<typename F,typename A>
struct other
{
template<typename f, typename a,
#ifndef PASS
typename = decltype(std::declval<F>()(std::declval<A>()))>
#else
typename = decltype(std::declval<f>()(std::declval<a>()))>
#endif
static std::true_type _Fn(int);
template<typename...>
static std::false_type _Fn(...);
typedef decltype(_Fn<F,A>(0)) type;
};
int main() {
static_assert(std::is_same<std::false_type,other<foo&,int>::type>::value,"PASSED");
return 0;
}
Compilation command:
g++ test.cc -std=c++11
为什么没有 -DPASS sfinae 在这里不起作用?
我一直在努力编译原始测试用例(没有 -DPASS),但我想出了解决方案(-DPASS),但我无法理解其中的区别?
因为与 class 方法相关的 SFINAE 对方法本身的模板参数起作用,而不是对包含 class.
的方法起作用
您可以使用以下技巧“转换”方法参数中的 class 参数来绕过此限制
template <typename T>
struct foo
{
template <typename U = T,
typename = /* some test over U */>
void bar ();
// ...
这样U
是方法bar
的模板参数,但与class、T
.[=14的模板参数类型相同=]
$cat test.cc
#include <type_traits>
struct foo{
};
template<typename F,typename A>
struct other
{
template<typename f, typename a,
#ifndef PASS
typename = decltype(std::declval<F>()(std::declval<A>()))>
#else
typename = decltype(std::declval<f>()(std::declval<a>()))>
#endif
static std::true_type _Fn(int);
template<typename...>
static std::false_type _Fn(...);
typedef decltype(_Fn<F,A>(0)) type;
};
int main() {
static_assert(std::is_same<std::false_type,other<foo&,int>::type>::value,"PASSED");
return 0;
}
Compilation command:
g++ test.cc -std=c++11
为什么没有 -DPASS sfinae 在这里不起作用? 我一直在努力编译原始测试用例(没有 -DPASS),但我想出了解决方案(-DPASS),但我无法理解其中的区别?
因为与 class 方法相关的 SFINAE 对方法本身的模板参数起作用,而不是对包含 class.
的方法起作用您可以使用以下技巧“转换”方法参数中的 class 参数来绕过此限制
template <typename T>
struct foo
{
template <typename U = T,
typename = /* some test over U */>
void bar ();
// ...
这样U
是方法bar
的模板参数,但与class、T
.[=14的模板参数类型相同=]