英文:
How do I guarantee that a class extends an implementation in c++?
问题
在C++中,你可以使用模板特化和类型限定来实现与Java中的类似功能。你可以使用以下方式来要求类型T实现IFoo接口:
template <typename T>
class container {
public:
// ... implementation
void addElement(T element) {
// 使用std::tuple的方式来获取position
auto pos = element.position();
if (std::get<0>(pos) > 10) {
// ... 做一些操作
}
}
};
在这个示例中,我们没有使用类似Java中的继承方式来限定类型T,而是直接要求类型T拥有position()和dimension()成员函数。如果类型T不符合这些要求,编译时将会出现错误。这种方式称为"模板要求",它依赖于类型T的实际属性而不是继承关系。
所以,你可以通过这种方式在C++中达到类似Java中的要求效果,而不需要显式地指定继承关系。
英文:
So say I have an interface that I want to use to specify specific properties a class should have in a container
class IFoo {
virtual std::tuple<int, int> position()= 0;
virtual std::tuple<int, int> dimension()= 0;
}
and I have a class that uses this interface
class Foo: public IFoo {
... implementation
}
and I have a container that I am creating
template <typename T>
class container {
... implementation
}
I want to demand that T uses the interface IFoo so that I can access the functions position and dimension of any generic object of type T. For example:
void container::addElement(T element){
if(std::get<0>(element.position()) > 10){
... do stuff
}
}
In java, it would be:
class container<T extends IFoo>
How do I do the equivalent in C++?
答案1
得分: 3
由于您正在使用C++17,最简单的解决方案是使用类型特征和std::enable_if_t
:
#include <tuple>
#include <type_traits>
class IFoo {
virtual std::tuple<int, int> position() = 0;
virtual std::tuple<int, int> dimension() = 0;
};
template<typename T,
typename = std::enable_if_t<std::is_base_of_v<IFoo, T>>>
class Container {
};
class Foo : public IFoo {
};
class Bar {};
Container<Foo> foo; // OK
Container<Bar> bar; // ERROR
一旦您升级到C++20,您可以使用概念:
#include <tuple>
#include <type_traits>
class IFoo {
virtual std::tuple<int, int> position() = 0;
virtual std::tuple<int, int> dimension() = 0;
};
template<typename T>
concept implementsIfoo = std::is_base_of<IFoo, T>::value;
template<implementsIfoo T>
class Container {
};
class Foo : public IFoo {
};
class Bar {};
Container<Foo> foo; // OK
Container<Bar> bar; // ERROR
英文:
Since you're using C++17, the simplest solution is to use type traits and std::enable_if_t
:
#include <tuple>
#include <type_traits>
class IFoo {
virtual std::tuple<int, int> position()= 0;
virtual std::tuple<int, int> dimension()= 0;
};
template<typename T,
typename=std::enable_if_t<std::is_base_of_v<IFoo, T>>>
class Container {
};
class Foo: public IFoo {
};
class Bar {};
Container<Foo> foo; // OK
Container<Bar> bar; // ERROR
And once you've updated to C++20 you can use concepts:
#include <tuple>
#include <type_traits>
class IFoo {
virtual std::tuple<int, int> position()= 0;
virtual std::tuple<int, int> dimension()= 0;
};
template<typename T>
concept implementsIfoo = std::is_base_of<IFoo, T>::value;
template<implementsIfoo T>
class Container {
};
class Foo: public IFoo {
};
class Bar {};
Container<Foo> foo; // OK
Container<Bar> bar; // ERROR
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论