[英]Overloading and template specialization for function call priority
参考以下代码:
我试图有条件地编译一堆函数,然后使用prioirty_tag
class
对它们进行“排序”。 我的问题是,如果我替换enable_if_t<is_nothrow_move_constructible<U>{}>* = nullptr>
与enable_if_t<is_nothrow_move_constructible<U>{}>>
输出不正确(默认为第一功能)。
那里到底发生了什么? 为什么添加* = nullptr
使其起作用?
#include <iostream>
#include <type_traits>
using namespace std;
template <size_t T>
struct priority_tag: priority_tag<T-1> {};
template <>
struct priority_tag<0> {};
template <typename T>
struct my_vec
{
template <typename U = T, typename = void>
void realloc_impl(priority_tag<0> pr)
{
cout << "Move throw construct\n";
};
//template <typename U = T, enable_if_t<is_copy_constructible<U>{}>> this wont work!
template <typename U = T, enable_if_t<is_copy_constructible<U>{}>* = nullptr>
void realloc_impl(priority_tag<1> pr)
{
cout << "copy construct \n";
};
//template <typename U = T, enable_if_t<is_copy_constructible<U>{}>> this wont work!
template <typename U = T, enable_if_t<is_nothrow_move_constructible<U>{}>* = nullptr>
void realloc_impl(priority_tag<2> pr)
{
cout << "nothrow move \n";
};
void realloc()
{
priority_tag<2> pr;
realloc_impl(pr);
}
const static int val = is_nothrow_move_constructible<T>{} ? 1 : is_copy_constructible<T>{} ? 2 : 3;
priority_tag<val> g;
};
class A {
public:
A() = default;
A(A&&) noexcept = default;
};
class B {
public:
B() = default;
B(B&&) = delete;
B(const B&) = default;
};
class C {
public:
C() = default;
C(C&&) {}
C(const C&) = delete;
};
int main()
{
my_vec<A> obj;
obj.realloc();
cout << obj.val;
}
尝试编译以下代码
template<void>
void foo(){}
我得到了编译器错误'void',它不是模板非类型参数的有效类型 。
作为模板参数,您可以传递:
1) 输入,然后使用class / typename声明它,如下所示:
template< class/typename A[optional] = void>
void foo2(){}
2) 非类型,则可以传递一些整数值,指针,左值引用等作为模板参数( 此处为完整列表)
template<void*>
void foo3(){}
3)模板类型参数
在您的示例中, is_nothrow_move_constructible
为A
返回true,然后编译器遇到以下行:
template <typename U = T, enable_if_t<is_nothrow_move_constructible<U>{}>>
什么是:
template <typename U = T, void>
此行的语法错误,并且编译器从重载集中删除了该成员函数模板。 您可以通过声明enable_if_t<is_nothrow_move_constructible<U>{}
作为类型参数来修复它:
template <typename U = T,
typename = enable_if_t<is_nothrow_move_constructible<U>{}> > // typename = void
void realloc_impl(priority_tag<2> pr)
{
cout << "nothrow move \n";
};
或作为非类型(指向void的指针),即您在示例中所做的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.