Here is an extremely simple code :
template <typename... Args,
typename std::enable_if<std::less<int>()(sizeof...(Args), 3), int>::type* = nullptr>
void test(std::tuple<Args...>)
{
}
int main()
{
test(std::make_tuple(1, 2));
}
Run Code Online (Sandbox Code Playgroud)
It's just simple function template with some enable_if condition. (for further SFINAE).
But it fails to compile in Visual Studio 2019 with C++ 17 setup.
error C2672: 'test': no matching overloaded function found
error C2783: 'void test(std::tuple<_Types...>)': could not deduce template argument for '__formal'
Run Code Online (Sandbox Code Playgroud)
However I found that it compiles well in GCC and …
在介绍概念和约束之前,有几种方法可以模拟此编译时检查。以“ order()”功能为例:(如何在LessThanComparable没有概念或约束的情况下实施是另一回事)
使用 static_assert
template <typename T, typename U>
void order(T& a, U& b)
{
static_assert(LessThanComparable<U,T>, "oh this is not epic");
if (b < a)
{
using std::swap;
swap(a, b);
}
}
Run Code Online (Sandbox Code Playgroud)
这种方法不适用于函数重载。
使用 typename = enable_if
template <typename T, typename U,
typename = std::enable_if_t<LessThanComparable<U,T>>>>
void order(T& a, U& b)
{
if (b < a)
{
using std::swap;
swap(a, b);
}
}
Run Code Online (Sandbox Code Playgroud)
如果过分“聪明”的家伙用手指定了第三个参数怎么办?
使用enable_if的函数原型:
template <typename T, typename U>
std::enable_if_t<LessThanComparable<U,T>>, void> order(T& a, U& b) …Run Code Online (Sandbox Code Playgroud)我正在编写一个在size_t上参数化的类模板,
template<size_t k>
class MyClass {...}
Run Code Online (Sandbox Code Playgroud)
参数k应该真的小于10,在这种情况下,如果它超出了这个范围,我希望它不能编译.我怎么能在C++ 11及更高版本中做到这一点?
MyClass<1> instance1; // ok
MyClass<2> instance2; // ok
MyClass<100> instance100; // fail to compile
Run Code Online (Sandbox Code Playgroud) 可以static_assert与模板别名一起使用吗?我知道如何使用SFINAE与模板的别名,以及如何使用static_assert同一个struct,但我想static_assert用化名给一个更清洁的错误消息。
我想到了以下用例:
#include <array>
constexpr bool is_valid(int n){
return n <= 10;
}
template <int n>
struct Foo {
static_assert(is_valid(n), "This class cannot handle more than 10 dimensions");
};
template <int n>
using Bar = std::array<float,n>;
template <int n, std::enable_if_t<is_valid(n)> * unused = nullptr>
using BarSFINAE = std::array<float,n>;
int main() {
Foo<5>();
// Foo<20>(); // Triggers the compiler-time static_assert
Bar<5>();
Bar<20>(); // TODO: Should trigger a compiler-time static_assert
BarSFINAE<5>();
// BarSFINAE<20>(); // …Run Code Online (Sandbox Code Playgroud)