#include <iostream>
template< typename, typename = void >
struct is_incrementable : std::false_type { };
template< typename T >
struct is_incrementable<T,
std::void_t<decltype( ++std::declval<T&>() )>
> : std::true_type { };
int main()
{
std::cout << is_incrementable<int>::value << std::endl; // prints 1
std::cout << is_incrementable<std::string>::value << std::endl; // prints 0
return 0;
}
ii)当我更改代码并删除void_t时
template< typename, typename = void >
struct is_incrementable : std::false_type { };
template< typename T >
struct is_incrementable<T,
decltype( ++std::declval<T&>() ) // void_t is removed
> : std::true_type { };
int main()
{
std::cout << is_incrementable<int>::value << std::endl; // prints 0
std::cout << is_incrementable<std::string>::value << std::endl; // prints 0
return 0;
}
0和0打印。is_incrementable
表示is_incrementable
,专门化是is_incrementable
,所以我们使用基本模板。对于字符串,专门化无论如何都失败了。
我的问题:iii)有趣的部分。如果现在我把第一行改为使用int作为默认类型
#include <iostream>
template< typename, typename = int > // !!! int is used now
struct is_incrementable : std::false_type { };
template< typename T >
struct is_incrementable<T,
decltype( ++std::declval<T&>() ) // void_t is removed
> : std::true_type { };
int main()
{
std::cout << is_incrementable<int>::value << std::endl; // prints 0
std::cout << is_incrementable<std::string>::value << std::endl; // prints 0
return 0;
}
有人能给我解释一下在iii)发生了什么吗?
当t
是int
时,decltype(++std::declval
是int&
,而不是int
。因此,要获得预期的输出,要么更改以下内容:
template< typename, typename = int >
struct is_incrementable : std::false_type { };
对此:
template< typename, typename = int & >
struct is_incrementable : std::false_type { };
否则更改以下内容:
template< typename T >
struct is_incrementable<T,
decltype( ++std::declval<T&>() )
> : std::true_type { };
template< typename T >
struct is_incrementable<T,
std::remove_reference_t<
decltype( ++std::declval<T&>() )
>
> : std::true_type { };
我知道,我可能可以用SFINAE和函数重载单独做到这一点。但是,对于像这样的情况,使用SFINAE是一种矫枉过正的做法。 所以我想知道是否有干净的方法来混合模板专业化和sfinae。
但是指定它是,因此它不再是模板类。它是否可以像虚函数一样专门化或重写?
还尝试在专门化的中进行模板方法专门化: 这一次它编译,但调用原始方法,即 解决方案
我有一个通用算法,需要访问其模板类型的特征。有一个特征类可以专门用于提供这些特征。 在我的类中使用此算法时,我想将其与类中定义的私有类型一起使用。 然而,专门化只能发生在或全局范围内,而我的类是不可访问的。 是否有可能以某种方式专门化具有私有类型的模板,至少在可访问此类型的范围内? 也许可以将这个专门化声明为一个类?
对于将SFINAE与可变模板类一起使用,我似乎找不到一个好的解决方案。 假设我有一个不喜欢引用的可变参数模板对象: 以及一个类,可以方便地检查参数包是否包含引用: 我如何使用它来专门化NoRef的情况下,引用存在于arg包?
在SO上回答另一个问题时,我遇到了一个有点可疑的gcc编译器错误。令人不快的片段是 谁的最后一行给出了著名的警告 好友声明'