具有不同类型的模板非类型参数
Template non-type parameter with different types
让我们假设输入模板参数 T
可能有也可能没有内部变量 bar
。我正在尝试编写一个结构,当我们有它时 returns bar
的值,而当我们没有时 returns 一些常量。这是我的尝试:
struct A {
static constexpr unsgined int bar = 20;
hasBar = true;
};
struct B {
hasBar = false;
};
template <typename T, typename std::enable_if<T::hasBar, int>::type>
struct getBar {
static constexpr unsigned int bar = T::bar;
};
template <typename T, typename std::enable_if<!T::hasBar, int>::type>
struct getBar {
static constexpr unsigned int bar = 0;
};
int main() {
getBar<A>::bar; // Expect 20
getBar<B>::bar; //Expect 0
}
我无法使用 C++14 编译此代码。编译器抱怨:"template non-type parameter has a different type".
为什么会出现这样的错误,我该如何解决?
Class 模板不能重载(如函数模板);您可以改用 specialization。例如
template <typename T, typename = void>
struct getBar {
static constexpr unsigned int bar = 0;
};
template <typename T>
struct getBar<T, std::enable_if_t<T::hasBar>> {
static constexpr unsigned int bar = T::bar;
};
不需要hasbar
直接检测::bar
是否存在
类似...
#include <type_traits>
#include <iostream>
struct A {
static constexpr unsigned int bar = 20;
};
struct B {
};
template <typename T,typename=void>
struct getBar {
static constexpr unsigned int bar = 0;
};
template <typename T>
struct getBar<T,std::void_t<decltype(T::bar)>> {
static constexpr unsigned int bar = T::bar;
};
int main() {
std::cout << getBar<A>::bar << std::endl; // Expect 20
std::cout << getBar<B>::bar << std::endl; //Expect 0
}
另一种不需要hasBar
但简单检测bar
存在的解决方案(如果与int
不同,也会保持bar
的原始类型)
struct A
{ static constexpr unsigned int bar = 20; };
struct B
{ };
template <typename T>
constexpr auto getBarHelper (int) -> decltype( T::bar )
{ return T::bar; }
template <typename T>
constexpr int getBarHelper (long)
{ return 0; }
template <typename T>
struct getBar
{ static constexpr auto bar { getBarHelper<T>(0) }; };
int main()
{
static_assert( 20u == getBar<A>::bar, "!" );
static_assert( 0 == getBar<B>::bar, "!" );
}
让我们假设输入模板参数 T
可能有也可能没有内部变量 bar
。我正在尝试编写一个结构,当我们有它时 returns bar
的值,而当我们没有时 returns 一些常量。这是我的尝试:
struct A {
static constexpr unsgined int bar = 20;
hasBar = true;
};
struct B {
hasBar = false;
};
template <typename T, typename std::enable_if<T::hasBar, int>::type>
struct getBar {
static constexpr unsigned int bar = T::bar;
};
template <typename T, typename std::enable_if<!T::hasBar, int>::type>
struct getBar {
static constexpr unsigned int bar = 0;
};
int main() {
getBar<A>::bar; // Expect 20
getBar<B>::bar; //Expect 0
}
我无法使用 C++14 编译此代码。编译器抱怨:"template non-type parameter has a different type".
为什么会出现这样的错误,我该如何解决?
Class 模板不能重载(如函数模板);您可以改用 specialization。例如
template <typename T, typename = void>
struct getBar {
static constexpr unsigned int bar = 0;
};
template <typename T>
struct getBar<T, std::enable_if_t<T::hasBar>> {
static constexpr unsigned int bar = T::bar;
};
不需要hasbar
::bar
是否存在
类似...
#include <type_traits>
#include <iostream>
struct A {
static constexpr unsigned int bar = 20;
};
struct B {
};
template <typename T,typename=void>
struct getBar {
static constexpr unsigned int bar = 0;
};
template <typename T>
struct getBar<T,std::void_t<decltype(T::bar)>> {
static constexpr unsigned int bar = T::bar;
};
int main() {
std::cout << getBar<A>::bar << std::endl; // Expect 20
std::cout << getBar<B>::bar << std::endl; //Expect 0
}
另一种不需要hasBar
但简单检测bar
存在的解决方案(如果与int
不同,也会保持bar
的原始类型)
struct A
{ static constexpr unsigned int bar = 20; };
struct B
{ };
template <typename T>
constexpr auto getBarHelper (int) -> decltype( T::bar )
{ return T::bar; }
template <typename T>
constexpr int getBarHelper (long)
{ return 0; }
template <typename T>
struct getBar
{ static constexpr auto bar { getBarHelper<T>(0) }; };
int main()
{
static_assert( 20u == getBar<A>::bar, "!" );
static_assert( 0 == getBar<B>::bar, "!" );
}