Reputation: 14406
I'm having the following problem:
struct MyType
{
int member;
};
template <typename T>
void func(T a)
{
using mytypedef = std::conditional<std::is_same_v<T, MyType>, decltype(T::member), char>;
// If T is MyType I want mytypedef to be of type MyType::member
}
int main()
{
MyType t{};
func(t); // Works fine because 'T::member' is an identifier
func(5); // Fails, 'T::member', undeclared identifier
}
What are the ways I can solve this problem?
Upvotes: 1
Views: 139
Reputation: 275936
T::member
is passed to conditional regardless of which branch the first bool says to take. There is no short circuit. And if it isn't valid, that is a hard error
template<class T>struct has_member{T member;};
using mytypedef = decltype(std::declval<std::conditional_t<std::is_same_v<T, MyType>, T, has_member<char>>>().member);
Upvotes: 0
Reputation: 173034
The problem is in func
, decltype(T::member)
is specified as template argument for std::conditional
, and it has to be valid whatever T
is.
On way is to make type trait for it.
template <typename T>
struct get_mytype {
using type = T;
};
template <>
struct get_mytype<MyType> {
using type = decltype(MyType::member);
};
then
template <typename T>
void func(T a)
{
using mytypedef = typename get_mytype<std::decay_t<T>>::type;
// If T is MyType I want mytypedef to be of type MyType::member
}
Upvotes: 1