sfinae 相关问题

替换失败不是错误。这是一种C ++编程技术,允许模板验证有关其模板参数的属性,从而允许在某些类型的对象可用时使用不同的特化。

检查类型重载给定的运算符

这个话题有很多相关问题,但我仍然对以下案例感到困惑: #包括 #包括 结构体A{}; struct B { void 运算符 + (const B&am...

回答 1 投票 0

使用 constexpr、SFINAE 和/或 type_traits 进行 char*、char 数组和字符串文字的重载解析

我遇到了一个有趣的挑战,我花了几个小时试图解决这个挑战,但经过大量研究和多次失败的尝试后,我发现自己在问这个问题。 我想写3

回答 2 投票 0

为什么可以用 std::is_const 和 std::is_reference 来实现 std::is_function ?

以下是 std::is_function 的实现吗? 模板 结构 is_function : std::integral_constant< bool, !std::is_const::value && !...

回答 2 投票 0

模板化的 require 子句失败

我有一组大致定义如下的类: 模板 类可迭代{ // 更多代码 }; 容器类:公共可迭代 { // 更多代码 }; T 级...

回答 1 投票 0

C++ 编译器实际上符合零大小数组 SFINAE 规则吗?

大约一两年前,我读到了 C++ 中的 SFINAE 规则。他们特别指出, 以下类型错误是 SFINAE 错误: ... 尝试创建一个 void 数组、引用数组、arr...

回答 1 投票 0

是否有办法将 C++ 模板类参数限制在一对一关系内?

比如有一个模板类: 模板 类示例; 如果一对 (A, B) 被特化,则其他类型不能用 A 特化。例如,(B, C) 是

回答 1 投票 0

使用enable_if和SFINAE时,函数参数类型推导(标准容器,例如向量)失败[重复]

我似乎不知道我哪里出了问题。 参见 https://ideone.com/WKsZSN 我正在尝试创建一个仅当其参数是某种暴露 t 的模板化类时才存在的函数...

回答 3 投票 0

尝试使用 SFINAE (std::enable_if) 和模板专业化时出现编译错误 [重复]

考虑代码: #包括 结构 CByteArray {}; 结构 HLVariant { HLVariant() {} HLVariant(const HLVariant&) {} HLVariant(const CByteArray&) {} };

回答 1 投票 0

使用`std::enable_if`时如何避免编写`::value`和`::type`? [cppx]

注意:这是一个问答题,旨在记录其他人可能认为有用的技术,并可能了解其他人更好的解决方案。欢迎大家补充

回答 3 投票 0

如何启用具有可变模板参数的类?

假设我有一个具有以下签名的类: 模板 A 级; 但是这个类的行为方式应该取决于其他一些参数,假设它是 va...

回答 2 投票 0

使用不同的enable_if条件选择成员函数[重复]

我试图根据类模板参数确定调用哪个版本的成员函数。我已经尝试过这个: #包括 #包括 模板<

回答 6 投票 0

在非模板成员函数上使用 std::enable_if 时出错[重复]

为什么此代码(M 类中的 fnc 值)无法通过 SFINAE 规则解析?我收到错误: 错误 1 错误 C2039:“类型”:不是以下成员 'std::tr1::

回答 2 投票 0

SFINAE:班级成员不能重新声明[重复]

我正在尝试创建自己的“智能迭代器”,我想使用 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;

回答 1 投票 0

通过SFINAE进行函数模板检测

我想编写一个函数,将 lambda 分派到外部库函数模板(如果库中存在此函数模板)或直接执行 lambda。 我们可以...

回答 0 投票 0

decltype 中的表达式是被执行,还是只是被检查以进行验证? [重复]

通过使用Expression SFINAE,您可以检测是否支持某些运算符或操作。 例如, 模板 自动 f(T& t, size_t n) -> decltype(t.reserve(n), void()...

回答 1 投票 0

是否可以使用SFINAE/模板来检查操作员是否存在? [重复]

我试图检查编译时是否存在运算符,如果不存在我只想忽略它,有什么办法可以做到这一点吗? 示例运算符: 模板 QDataStream&操作...

回答 3 投票 0

使用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<< 是全局的,而不是成员,尽管实现的代码看起来不错在这方面)。

回答 2 投票 0

如何在编译时检查表达式是否非法?

我的应用程序中有一个问题,我想断言函数应用程序将被编译器拒绝。有没有办法通过 SFINAE 检查这一点? 例如,假设我会...

回答 3 投票 0

sizeof(E) 是一种惯用的 SFINAE 技术来检查 E 是否是有效表达式吗?

我刚刚知道如何检查 if 运算符<< is provided for a type. template T& lvalue_of_type(); 模板 T rvalue_of_type(); 模板 斯特...

回答 3 投票 0

SFINAE 有什么好的用途?

我想了解更多模板元编程。我知道 SFINAE 代表“替换失败不是错误”。但有人可以告诉我 SFINAE 的好用处吗?

回答 10 投票 0

© www.soinside.com 2019 - 2024. All rights reserved.