为什么这个 std::enable_if 不起作用
Why does this std::enable_if not work
从这个问题Why should I avoid std::enable_if in function signatures看来我应该可以写
#include <type_traits>
#include <iostream>
enum Class {
Primary,
Secondary
};
template<Class C>
class Entity {
public:
template<typename Cls = C, typename Sec = Secondary, std::enable_if<std::is_same<Cls, Sec>::value>::type = 0>
void onlyLegalForSecondaryEntities() {
std::cout << "Works" << std::endl;
}
};
int main() {
Entity<Secondary> e;
e.onlyLegalForSecondaryEntities();
return 0;
}
但是编译失败并出现错误 prog.cpp:13:7: note: template argument deduction/substitution failed
如何编译此代码?
您将 Class
用于 enum
是一个糟糕的主意。不要使用大小写不同的语言关键字作为类型名称。
C
是 Class
类型的编译时值。不是类型。
typename Cls = C
尝试将类型 Class
的值分配给一个类型。这是类似于说 "picking up a sad" 的错误。 sad 不是名词,不是随便捡的。
使代码编译通过的最简单方法是完全删除 onlyLegalForSecondaryEntities
以及对它的所有引用。
一般来说,根据标准,您不能拥有仅在某些参数传递给模板时有效的模板方法 class 它存在于其中。这样做会使您的程序格式错误,不需要诊断。
这很接近:
template<Class Cls = C,
std::enable_if_t< Cls == Secondary, int> =0
>
void onlyLegalForSecondaryEntities() {
std::cout << "Works" << std::endl;
}
除了即使在 Entity<Primary>
上,您也可以 .onlyLegalForSecondaryEntities<Secondary>()
。
如果你不想允许这个,我会使用 CRTP。
template<bool b, class D>
struct empty_if_false {};
template<class D>
struct empty_if_false<true, D> {
D* self() { return static_cast<D*>(this); }
D const* self() const { return static_cast<D*>(this); }
void onlyLegalForSecondaryEntities() {
// use self() instead of this in this method to get at a this pointer
std::cout << "Works" << std::endl;
}
};
然后:
template<Class C>
class Entity:public empty_if_false< C==Secondary, Entity<C> > {
有条件有方法
从这个问题Why should I avoid std::enable_if in function signatures看来我应该可以写
#include <type_traits>
#include <iostream>
enum Class {
Primary,
Secondary
};
template<Class C>
class Entity {
public:
template<typename Cls = C, typename Sec = Secondary, std::enable_if<std::is_same<Cls, Sec>::value>::type = 0>
void onlyLegalForSecondaryEntities() {
std::cout << "Works" << std::endl;
}
};
int main() {
Entity<Secondary> e;
e.onlyLegalForSecondaryEntities();
return 0;
}
但是编译失败并出现错误 prog.cpp:13:7: note: template argument deduction/substitution failed
如何编译此代码?
您将 Class
用于 enum
是一个糟糕的主意。不要使用大小写不同的语言关键字作为类型名称。
C
是 Class
类型的编译时值。不是类型。
typename Cls = C
尝试将类型 Class
的值分配给一个类型。这是类似于说 "picking up a sad" 的错误。 sad 不是名词,不是随便捡的。
使代码编译通过的最简单方法是完全删除 onlyLegalForSecondaryEntities
以及对它的所有引用。
一般来说,根据标准,您不能拥有仅在某些参数传递给模板时有效的模板方法 class 它存在于其中。这样做会使您的程序格式错误,不需要诊断。
这很接近:
template<Class Cls = C,
std::enable_if_t< Cls == Secondary, int> =0
>
void onlyLegalForSecondaryEntities() {
std::cout << "Works" << std::endl;
}
除了即使在 Entity<Primary>
上,您也可以 .onlyLegalForSecondaryEntities<Secondary>()
。
如果你不想允许这个,我会使用 CRTP。
template<bool b, class D>
struct empty_if_false {};
template<class D>
struct empty_if_false<true, D> {
D* self() { return static_cast<D*>(this); }
D const* self() const { return static_cast<D*>(this); }
void onlyLegalForSecondaryEntities() {
// use self() instead of this in this method to get at a this pointer
std::cout << "Works" << std::endl;
}
};
然后:
template<Class C>
class Entity:public empty_if_false< C==Secondary, Entity<C> > {
有条件有方法