替换失败不是错误。这是一种C ++编程技术,允许模板验证有关其模板参数的属性,从而允许在某些类型的对象可用时使用不同的特化。
比如有一个模板类: 模板 类示例; 如果一对 (A, B) 被特化,则其他类型不能用 A 特化。例如,(B, C) 是
使用enable_if和SFINAE时,函数参数类型推导(标准容器,例如向量)失败[重复]
我似乎不知道我哪里出了问题。 参见 https://ideone.com/WKsZSN 我正在尝试创建一个仅当其参数是某种暴露 t 的模板化类时才存在的函数...
尝试使用 SFINAE (std::enable_if) 和模板专业化时出现编译错误 [重复]
考虑代码: #包括 结构 CByteArray {}; 结构 HLVariant { HLVariant() {} HLVariant(const HLVariant&) {} HLVariant(const CByteArray&) {} };
使用`std::enable_if`时如何避免编写`::value`和`::type`? [cppx]
注意:这是一个问答题,旨在记录其他人可能认为有用的技术,并可能了解其他人更好的解决方案。欢迎大家补充
假设我有一个具有以下签名的类: 模板 A 级; 但是这个类的行为方式应该取决于其他一些参数,假设它是 va...
我试图根据类模板参数确定调用哪个版本的成员函数。我已经尝试过这个: #包括 #包括 模板<
在非模板成员函数上使用 std::enable_if 时出错[重复]
为什么此代码(M 类中的 fnc 值)无法通过 SFINAE 规则解析?我收到错误: 错误 1 错误 C2039:“类型”:不是以下成员 'std::tr1::
我正在尝试创建自己的“智能迭代器”,我想使用 SFINAE 根据迭代器的标签来创建一些运算符: 这是我的代码: 模板 我正在尝试创建自己的“智能迭代器”,并且我想使用 SFINAE 根据迭代器的标签创建一些运算符: 这是我的代码: template<class Iterator, class Predicat, class Tag> class RangeFilterIterator { public: RangeFilterIterator(Iterator begin, Iterator end, Predicat predicat) : mBegin(begin), mEnd(end), mPredicat(predicat) {} bool operator !=(RangeFilterIterator const &r) { return mBegin != r.mBegin; } typename Iterator::value_type &operator*() {return *mBegin;} RangeFilterIterator &operator++() { while(mBegin != mEnd && mPredicat(*mBegin++)); return *this; } template<class = std::enable_if_t<std::is_base_of<std::random_access_iterator_tag, Tag>::value>> RangeFilterIterator &operator+(std::size_t n) { while(n--) ++(*this); return *this; } template<class = std::enable_if_t<!std::is_base_of<std::random_access_iterator_tag, Tag>::value>> RangeFilterIterator &operator+(std::size_t n) = delete; private: Iterator mBegin, mEnd; Predicat mPredicat; }; template<typename Container, typename Predicate> auto RangeFilter(Container const &c, Predicate p) { using Iterator = RangeFilterIterator<typename Container::iterator, Predicate, typename Container::iterator::iterator_category>; Iterator begin(const_cast<Container&>(c).begin(), const_cast<Container&>(c).end(), p); Iterator end(const_cast<Container&>(c).end(), const_cast<Container&>(c).end(), p); return Range(begin, end); } 在RangeFilterIterator &operator+(std::size_t n) = delete行我收到错误:class member cannot be redeclared。 我对模板不太“擅长”,但我认为对于 SFINAE,只会“声明”两者之一。我错过了什么吗?还可以做别的吗? 好吧,当我使用返回类型参数而不是模板参数时,它可以工作。 template<class tag = Tag> std::enable_if_t<std::is_base_of<std::random_access_iterator_tag, tag>::value, RangeFilterIterator> &operator+(std::size_t n) { while(n--) ++(*this); return *this; } template<class tag = Tag> std::enable_if_t<!std::is_base_of<std::random_access_iterator_tag, tag>::value, RangeFilterIterator> &operator+(std::size_t n) = delete;
我想编写一个函数,将 lambda 分派到外部库函数模板(如果库中存在此函数模板)或直接执行 lambda。 我们可以...
decltype 中的表达式是被执行,还是只是被检查以进行验证? [重复]
通过使用Expression SFINAE,您可以检测是否支持某些运算符或操作。 例如, 模板 自动 f(T& t, size_t n) -> decltype(t.reserve(n), void()...
是否可以使用SFINAE/模板来检查操作员是否存在? [重复]
我试图检查编译时是否存在运算符,如果不存在我只想忽略它,有什么办法可以做到这一点吗? 示例运算符: 模板 QDataStream&操作...
使用SFINAE查询全球运营商<<? [duplicate]
我想要几个重载的全局 to_string() 函数,它们接受某种类型 T 并将其转换为其字符串表示形式。对于一般情况,我希望能够写: 模板 我想要几个重载的全局 to_string() 函数,它们采用某种类型 T 并将其转换为字符串表示形式。对于一般情况,我希望能够写: template<typename T,class OutputStringType> inline typename enable_if<!std::is_pointer<T>::value && has_insertion_operator<T>::value, void>::type to_string( T const &t, OutputStringType *out ) { std::ostringstream o; o << t; *out = o.str(); } 到目前为止我的has_insertion_operator实现是: struct sfinae_base { typedef char yes[1]; typedef char no[2]; }; template<typename T> struct has_insertion_operator : sfinae_base { template<typename U> static yes& test( U& ); template<typename U> static no& test(...); static std::ostream &s; static T const &t; static bool const value = sizeof( test( s << t ) ) == sizeof( yes ); // line 48 }; (借用了this 和这个。) 这似乎有效。 但现在我想要一个 to_string 的重载版本,适用于 not 有 operator<< 但 do 有自己的 to_string() member 函数的类型,即: template<class T,class OutputStringType> inline typename enable_if<!has_insertion_operator<T>::value && has_to_string<T,std::string (T::*)() const>::value, void>::type to_string( T const &t, OutputStringType *out ) { *out = t.to_string(); } has_to_string的实现是: #define DECL_HAS_MEM_FN(FN_NAME) \ template<typename T,typename S> \ struct has_##FN_NAME : sfinae_base { \ template<typename SignatureType,SignatureType> struct type_check; \ template<class U> static yes& test(type_check<S,&U::FN_NAME>*); \ template<class U> static no& test(...); \ static bool const value = sizeof( test<T>(0) ) == sizeof( yes ); \ } DECL_HAS_MEM_FN( to_string ); (这部分似乎工作正常。它改编自this。) 然而,当我: struct S { string to_string() const { return "42"; } }; int main() { string buf; S s; to_string( s, &buf ); // line 104 } 我得到: foo.cpp: In instantiation of ‘const bool has_insertion_operator<S>::value’: foo.cpp:104: instantiated from here foo.cpp:48: error: no match for ‘operator<<’ in ‘has_insertion_operator<S>::s << has_insertion_operator<S>::t’ SFINAE 似乎没有发生。如何正确编写 has_insertion_operator 以便确定全局 operator<< 是否可用? 仅供参考:我正在使用 g++ 4.2.1(它作为 Mac OS X 上 Xcode 的一部分提供)。 另外,我希望代码只是标准 C++03,没有第三方库,例如 Boost。 谢谢! 我应该更忠实于这个的答案。 一个可行的实现是: namespace has_insertion_operator_impl { typedef char no; typedef char yes[2]; struct any_t { template<typename T> any_t( T const& ); }; no operator<<( std::ostream const&, any_t const& ); yes& test( std::ostream& ); no test( no ); template<typename T> struct has_insertion_operator { static std::ostream &s; static T const &t; static bool const value = sizeof( test(s << t) ) == sizeof( yes ); }; } template<typename T> struct has_insertion_operator : has_insertion_operator_impl::has_insertion_operator<T> { }; 我相信它不实际上依赖于SFINAE。 第 48 行 value 的初始化程序不在 SFINAE 工作的上下文中。尝试将表达式移动到函数声明中。 #include <iostream> struct sfinae_base { typedef char yes[1]; typedef char no[2]; }; template<typename T> struct has_insertion_operator : sfinae_base { // this may quietly fail: template<typename U> static yes& test( size_t (*n)[ sizeof( std::cout << * static_cast<U*>(0) ) ] ); // "..." provides fallback in case above fails template<typename U> static no& test(...); static bool const value = sizeof( test<T>( NULL ) ) == sizeof( yes ); }; 但是,我不得不质疑这件事的复杂程度。我看到非正交机制会相互冲突(to_string 与 operator<<),并且我听到糟糕的假设被抛弃(例如,operator<< 是全局的,而不是成员,尽管实现的代码看起来不错在这方面)。
我的应用程序中有一个问题,我想断言函数应用程序将被编译器拒绝。有没有办法通过 SFINAE 检查这一点? 例如,假设我会...
sizeof(E) 是一种惯用的 SFINAE 技术来检查 E 是否是有效表达式吗?
我刚刚知道如何检查 if 运算符<< is provided for a type. template T& lvalue_of_type(); 模板 T rvalue_of_type(); 模板 斯特...
我想了解更多模板元编程。我知道 SFINAE 代表“替换失败不是错误”。但有人可以告诉我 SFINAE 的好用处吗?
我遇到了有关正确使用enable_if和模板专业化的问题。 修改示例后(出于保密原因),下面是一个可比较的示例: 我...
无法用 std::enable_if 作为函数参数推导出模板参数
所以,我正在遵循此网页上某处代码设置的示例: http://eli.thegreenplace.net/2014/sfinae-and-enable_if/ 这是我所拥有的: 模板 void fun(const type...
如何构建一个std数组/向量组成的类,对应参数是否为constexpr
我正在补充一个类似Python的范围类(我们称之为Range)。 如果参数是 constexpr,我想使用 std::array 来存储数据,否则使用 std::vector 来存储数据。 我想知道我是否可以使用相同的
请考虑以下 C++14 代码: #包括 模板 类酒吧{ static_assert(std::is_destructible::value, "T 必须是可破坏的&...