使用 std::enable_if 作为 templ 时的默认模板参数.参数:为什么可以使用两个仅在enable_if参
Default template argument when using std::enable_if as templ. param.: why OK with two template functions that differ only in the enable_if parameter?
在cpp首选项的std::enable_if
语言参考中,包括以下注释
笔记
一个常见的错误是声明两个不同的函数模板 仅在其默认模板参数中。这是非法的,因为 默认模板参数不是函数模板的一部分 签名,并使用 相同的签名是非法的。
在下面的示例中的模板函数中,在我看来,这种情况发生了。 也就是说,这两个模板函数似乎(对我来说)onlyForDerivedObjects(...)
区别仅在于它们的默认模板参数。我意识到我在这里错过了一些东西,希望有人能向我解释这一点,或者为我指出我可能为自己找到顿悟的方向。
-
问题:W.r.t. 上面的引用,为什么下面的示例编译并运行良好:当我认为下面的模板函数中的
typename std::enable_if ...
部分会产生两个模板函数仅在默认模板参数上不同的情况时,我是否错误地分类了它?
例
- 现场演示
基类和派生类:
class BaseA
{
public:
int getInt() const { return 21; };
};
class DerivedA : public BaseA {};
class BaseB
{
public:
int getAnotherInt() const { return 33; };
};
class DerivedB : public BaseB {};
使用以下模板函数
/* template functions that, seemingly, only differ in their
default template arguments? */
template< class T,
typename std::enable_if<std::is_base_of<BaseA, T>::value>::type* = nullptr >
int onlyForDerivedObjects(const T& obj)
{
return 2*obj.getInt();
}
template< class T,
typename std::enable_if<std::is_base_of<BaseB, T>::value>::type* = nullptr >
int onlyForDerivedObjects(const T& obj)
{
return 3*obj.getAnotherInt();
}
编译和运行良好 ( g++ -Wall -std=c++11 ...
, g++ 4.9.3
)
#include <iostream>
#include <type_traits>
/* ... classes and template functions as above */
/* template argument deduction seems to work fine */
int main()
{
DerivedA* objA = new DerivedA();
DerivedB* objB = new DerivedB();
std::cout << onlyForDerivedObjects(*objA) << std::endl; // 42
std::cout << onlyForDerivedObjects(*objB) << std::endl; // 99
return 0;
}
笔记
一个常见的错误是声明两个函数模板,它们仅在默认模板参数上有所不同。这是非法的,因为默认模板参数不是函数模板签名的一部分,并且声明具有相同签名的两个不同的函数模板是非法的。
您的函数不仅在默认模板参数上有所不同,而且在模板参数上也不同,因此具有不同的签名。
在这两种情况下,默认模板参数都是 nullptr
,但第二个模板参数在每种情况下都不同。
常见的错误是:
template <typename T, typename = std::enable_if_t<cond>>
void foo()
template <typename T, typename = std::enable_if_t<!cond>>
void foo()
两者都声明
template <typename, typename>
void foo();
相关文章:
- 如何将enable-if与模板参数和参数包一起使用
- 将 out/in out 参数与 if/switch 的 init 语句一起使用
- MSVC使用constexpr-if从可变模板方法中的基本模板参数中吞下const
- 在if constexpr中使用带参数包的概念时,升级到gcc 9后出现编译错误
- clang 格式堆叠所有 if 语句参数,如果它们太长
- 在 constexpr-if 条件下比较 constexpr 函数参数会导致错误
- 在通用 lambda 中使用 constexpr-if 来确定参数的类型
- "if (argc < 2 || argc > 2)"应该有 2 个参数吗?&终止在抛出'std::out_of_range'错误实例后调用
- 是否可以使用模板非类型参数使用#if指令?(矢量多合一类)
- 递归可变参数函数调用对简单 if.else 语句的性能
- 是否有等效的 #if 可以评估模板参数
- 我可以在 if 语句中使用"x=2"作为参数吗?
- 为什么if语句中未定义的参数不会导致segfault或其他错误
- 如何启动具有许多布尔参数的函数模板,而不使用 2^n if 语句
- 函数参数内的If语句;分支类型
- "IF"参数评估顺序?
- 隐藏c++参数的有趣案例(参数没有在if块中隐藏)
- 考虑到模板参数,正在更改if语句条件
- QT5迁移和Boost:if.hp:宏参数不匹配错误
- 如何使用在C++中具有多个参数的if语句来调用多个函数