访问类型成员
Access type member
在我的示例中,我有一个类Foo<T>
。在我的函数test
中,我需要获取Foo
否则为普通类型的模板参数。首先,我开始使用std::conditional
但忘记了模板参数必须全部有效,无论选择哪一个。是否为non-Foo
类型创建类型专用化的唯一方法?
例
#include <type_traits>
template <typename TYPE>
class Foo
{
public:
using M = TYPE;
};
template <typename T>
void test(const T& a)
{
// actually I would have used !is_foo<T>::value for the first arg
// but this check is fine to minimise the example
using MY_TYPE = typename std::conditional<
std::is_same<T, int>::value,
T,
typename T::M>::type; // <---Error: error: type 'int' cannot be used prior to '::' because it has no members
}
int main()
{
test(Foo<int>()); // MY_TYPE must be int
test(int()); // MY_TYPE must be int
return 0;
}
好吧,
你可以做一个UnFoo
助手来获得适合你的类型:
template <typename T>
struct UnFoo {
using type = T;
};
template <typename T>
struct UnFoo<Foo<T>> {
using type = T;
};
template <typename T>
void test(const T& a)
{
using MY_TYPE = typename UnFoo<T>::type; //maybe with a helper to get rid of typename
}
另一种选择是为Foo<T>
编写重载并将其委托给另一个函数,但这取决于您的实际test
函数的作用。
你可以
做一些void_t魔法,让SFINAE想办法帮助你:
#include <type_traits>
#include <iostream>
#include <typeinfo>
template <typename TYPE>
class Foo
{
public:
using M = TYPE;
};
template<typename... Ts> struct make_void { typedef void type;};
template<typename... Ts> using void_t = typename make_void<Ts...>::type;
// primary template handles types that have no nested ::T member:
template< class T, class = void_t<> >
struct M_or_T { using type = T; };
// specialization recognizes types that do have a nested ::T member:
template< class T >
struct M_or_T<T, void_t<typename T::M>> { using type = typename T::M; };
template <typename T>
void test(const T& a)
{
using MY_TYPE = typename M_or_T<T>::type;
std::cout << typeid(MY_TYPE).name() << "n";
}
int main()
{
test(Foo<int>()); // MY_TYPE must be int
test(int()); // MY_TYPE must be int
return 0;
}
发生的情况是,M_or_T
替换的第二次重载对于int
(以及没有类型成员M
的任何类型(失败,因此选择了第一个重载。对于具有类型成员M
的类型,选择更专业的第二次重载。
#include <type_traits>
template <typename TYPE>
class Foo
{
public:
using M = TYPE;
};
template <typename T>
void test(const Foo<T>& a)
{
using MY_TYPE = Foo<T>::M;
testOther<MY_TYPE>(a);
}
template <typename T>
void test(const T& a)
{
using MY_TYPE = T;
testOther<MY_TYPE>(a);
}
template <typename T, typename S>
void testOther(const S& a)
{
// do stuff
}
int main()
{
test(Foo<int>()); // MY_TYPE must be int
test(int()); // MY_TYPE must be int
return 0;
}
我不确定你想要什么,但我希望这就是你想要的。可能有点不对劲。我没有编译这个。
相关文章:
- c++类声明时,相同的例程,不同的成员变量类型
- 这是关于成员访问规则的正确摘要吗
- 为什么我在空指针错误(链表)中获取成员访问权限
- 是否可以根据其数据成员的类型确定类型的大小
- 标准对此指向成员函数类型模板参数有何说明?是我的代码有误,还是 MSVS 16.6 有问题?
- 成员访问是否在空指针上定义C++?
- 如何访问模板参数的成员?“成员访问不完整的类型”
- C++ Qt4.8 :: 将对象传递给另一个类 - 成员访问不完整类型错误
- C++:错误:成员访问不完整的类型,未使用的参数[-Werror,-Wunused-parameter]
- 成员访问不完整类型错误:模板化结构C++
- 访问联合成员需要类型转换
- 错误:成员访问不完整类型:前向声明
- 应用于不完整类型的变量的成员访问表达式
- 访问类的成员。此类的对象从未实例化。所有成员的类型均为静态
- 为什么我们不能通过类成员访问表达式使用嵌套类型?
- 访问类型成员
- QtPropertyBrowser:成员访问为不完整类型
- c++成员访问不完整类型,尽管包含头文件
- 从私有成员值类型 (bool) 读取的 VC++ 访问冲突
- 是否可以像重载另一种类型的成员访问运算符一样解析静态成员