【问题标题】:using template aliases combined with partial specialization of templates使用模板别名与模板的部分特化相结合
【发布时间】:2020-11-20 21:20:40
【问题描述】:

我正在思考为什么以下会导致编译错误。 我是元编程的新手,但根据我对 SFINAE 原则的理解,以下函数是互斥的,因此它不是对现有函数的“重新定义”。

#include <type_traits>

template<typename T>
using IsNotEnum = typename std::enable_if<!std::is_enum<T>::value>::type;

template<typename T>
using IsEnum = typename std::enable_if<std::is_enum<T>::value>::type;

template<typename T, typename = IsNotEnum<T>>
void doSomething()
{
}

template<typename T, typename = IsEnum<T>>
void doSomething()
{
}

g++ 7.5 抱怨如下:

error: redefinition of ‘template<class T, class> void doSomething()’
void doSomething()
  ^~~~~~~~~~~
note: ‘template<class T, class> void doSomething()’ previously declared here
void doSomething()

【问题讨论】:

标签: c++ templates alias sfinae


【解决方案1】:

尝试如下重写你的函数

template<typename T, IsNotEnum<T> = nullptr>
void doSomething()
{
}

template<typename T, IsEnum<T> = nullptr>
void doSomething()
{
}

和你的usings如下

template <typename T>
using IsNotEnum = typename std::enable_if<!std::is_enum<T>::value, std::nullptr_t>::type;

template <typename T>
using IsEnum = typename std::enable_if<std::is_enum<T>::value, std::nullptr_t>::type;

或者简单地说,如果您有 C++14 或更新版本的编译器,

template <typename T>
using IsNotEnum = std::enable_if_t<!std::is_enum<T>::value, std::nullptr_t>;

template <typename T>
using IsEnum = std::enable_if_t<std::is_enum<T>::value, std::nullptr_t>;

您的代码中的问题是您不能编写两个仅针对模板默认类型/值不同的不同函数。

因此,删除默认值,SFINAE 不会禁用不需要的功能。所以你有一个函数冲突。

仅删除类型(在等号左侧)SFINAE 删除不需要的函数。

【讨论】:

  • 很好,我没有意识到“typename =”是默认类型分配。有了那条信息,它就很有意义了。谢谢
猜你喜欢
  • 2021-09-11
  • 2017-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-30
  • 1970-01-01
相关资源
最近更新 更多