我想进入更多的模板元编程.我知道SFINAE代表"替换失败不是错误".但是有人能告诉我SFINAE的用处吗?
什么是C++中的SFINAE?
能不能用不熟悉C++的程序员理解的话来解释它?另外,像Python这样的语言中的SFINAE对应的概念是什么?
我的应用程序中有一个问题,我想声明函数应用程序将被编译器拒绝.有没有办法用SFINAE来检查?
例如,假设我想验证std::transform的const范围是违法的.这是我到目前为止所拥有的:
#include <algorithm>
#include <functional>
#include <iostream>
namespace ns
{
using std::transform;
template<typename Iterator1, typename Iterator2, typename UnaryFunction>
struct valid_transform
{
static Iterator1 first1, last1;
static Iterator2 first2;
static UnaryFunction f;
typedef Iterator2 yes_type;
typedef struct {yes_type array[2];} no_type;
static no_type transform(...);
static bool const value = sizeof(transform(first1, last1, first2, f)) == sizeof(yes_type);
};
}
int main()
{
typedef int *iter1;
typedef const int *iter2;
typedef std::negate<int> func;
std::cout << "valid transform compiles: " << …Run Code Online (Sandbox Code Playgroud) 在C++ 11中,SFINAE很容易判断表达式是否有效.举个例子,假设检查某些东西是否可流动:
template <typename T>
auto print_if_possible(std::ostream& os, const T& x)
-> decltype(os << x, void());
Run Code Online (Sandbox Code Playgroud)
print_if_possible将只参加重载解析如果os << x是合式表达.
我需要在C++ 03中做同样的事情,我发现这sizeof可能有所帮助(因为我需要一个表达式的未评估上下文).这就是我想出的:
template <int> struct sfinaer { };
template <typename T>
void print_if_possible(std::ostream& os, const T& x,
sfinaer<sizeof(os << x)>* = NULL);
Run Code Online (Sandbox Code Playgroud)
似乎g ++和clang ++的最新版本都接受了这个sizeof版本-std=c++03 -Wall -Wextra.
代码是否保证在C++ 03中按预期工作?
它是正确的结论是C++ 11的表达SFINAE的任何使用可回迁C++ 03使用到sfinaer和sizeof?
我想用以下形式表达一个static_assert:
static_assert(expression should not compile);
Run Code Online (Sandbox Code Playgroud)
让我添加一个完整的示例:
template <bool Big>
struct A{};
template <>
struct A<true>
{
void a() {}
};
A<false> b;
static_assert(!compile(b.a()));
or
static_assert(!compile(A<false>::a()));
Run Code Online (Sandbox Code Playgroud)
因此,该想法是要确保不会编译表达式(具有有效语法)。
如果可能的话,该解决方案仅使用C ++ 11会更好。
c++ ×5
sfinae ×4
c++-concepts ×1
c++-faq ×1
c++03 ×1
c++11 ×1
decltype ×1
sizeof ×1
templates ×1
type-traits ×1