如何通过 class 模板专门化运算符函数类型
How can I specialize a operator function type by class template
我有一个像下面这样的 class 并且想通过 class 模板 T 来特化 '->' 运算符。特化应该取决于类型 T 是否是指针类型或不。我已经搜索了解决方案,但没有找到针对此特定问题的任何解决方案。
template <typename T>
class C
{
public:
// when T is a pointer type
T operator->()
{
return value;
}
// when T is not a pointer type
const T* operator->() const
{
return &value;
}
private:
T value;
};
void test()
{
struct Test
{
int x, y;
};
C<Test> c1;
C<Test*> c2;
c1->x = 5; // should both work
c2->x = 5; // ignoring the fact, that c2's value is undefined
}
感谢您的帮助!
你需要partial specialization
而且您还需要小心取消引用指针。您的原始示例可能会崩溃。
template <typename T>
class C
{
public:
explicit C(const T& v = T()): value(v) {}
// when T is not a pointer type
T* operator->()
{
return &value;
}
private:
T value;
};
template <typename T>
class C<T*>
{
public:
explicit C(T* v = nullptr): value(v) {}
// when T is a pointer type
T* operator->()
{
return value;
}
private:
T* value;
};
或者如果你有兼容 C++17 的编译器,你可以使用 if constexpr:
template <typename T>
class C
{
public:
explicit C(const T& v = T()): value(v) {}
// when T is not a pointer type
auto operator->()
{
if constexpr (std::is_pointer_v<T>)
return value;
else
return &value;
}
private:
T value;
};
测试一下:
int main()
{
struct Test
{
int x, y;
};
C<Test> c1({1, 2});
Test t = {3, 4};
C<Test*> c2(&t); // Initialize the pointer with some valid address, we are going to dereference it!
c1->x = 5;
c2->x = 5;
std::cout << c1->x << ' ' << c1->y << ' ' << t.x << ' ' << t.y << '\n';
}
我有一个像下面这样的 class 并且想通过 class 模板 T 来特化 '->' 运算符。特化应该取决于类型 T 是否是指针类型或不。我已经搜索了解决方案,但没有找到针对此特定问题的任何解决方案。
template <typename T>
class C
{
public:
// when T is a pointer type
T operator->()
{
return value;
}
// when T is not a pointer type
const T* operator->() const
{
return &value;
}
private:
T value;
};
void test()
{
struct Test
{
int x, y;
};
C<Test> c1;
C<Test*> c2;
c1->x = 5; // should both work
c2->x = 5; // ignoring the fact, that c2's value is undefined
}
感谢您的帮助!
你需要partial specialization 而且您还需要小心取消引用指针。您的原始示例可能会崩溃。
template <typename T>
class C
{
public:
explicit C(const T& v = T()): value(v) {}
// when T is not a pointer type
T* operator->()
{
return &value;
}
private:
T value;
};
template <typename T>
class C<T*>
{
public:
explicit C(T* v = nullptr): value(v) {}
// when T is a pointer type
T* operator->()
{
return value;
}
private:
T* value;
};
或者如果你有兼容 C++17 的编译器,你可以使用 if constexpr:
template <typename T>
class C
{
public:
explicit C(const T& v = T()): value(v) {}
// when T is not a pointer type
auto operator->()
{
if constexpr (std::is_pointer_v<T>)
return value;
else
return &value;
}
private:
T value;
};
测试一下:
int main()
{
struct Test
{
int x, y;
};
C<Test> c1({1, 2});
Test t = {3, 4};
C<Test*> c2(&t); // Initialize the pointer with some valid address, we are going to dereference it!
c1->x = 5;
c2->x = 5;
std::cout << c1->x << ' ' << c1->y << ' ' << t.x << ' ' << t.y << '\n';
}