这是(简化的)基类:
template <class T>
class SharedObject
{
protected:
QExplicitlySharedDataPointer <typename T::Data> d;
};
Run Code Online (Sandbox Code Playgroud)
以下是派生的:
class ThisWontCompile : public SharedObject <ThisWontCompile>
{
private:
friend class SharedObject;
struct Data : public QSharedData
{
int id;
};
};
Run Code Online (Sandbox Code Playgroud)
是否有任何解决方法从SharedObject访问ThisWontCompile :: Data?使用基础对象中的派生对象究竟能做什么,究竟什么不能完成?
在VC++ 10中,以下示例因错误C2027而失败:"使用未定义类型'X'".但是g ++ 4.6编译得很好.
template<class T>
class C
{
static const size_t size = sizeof(T);
};
class X : public C<X> { };
Run Code Online (Sandbox Code Playgroud)
那么哪一个是对的?我将如何做到这一点,以便它适用于主流编译器?
这并不是什么大不了的事,因为VC++仍然允许在C的成员函数中使用sizeof(T).我只需要重复一些烦人的长类型定义.
编辑: 我意识到我的例子很糟糕,因为我真正想做的是将大小用作编译时常量,这样:
template<size_t size> class C2 { };
template<class T>
class C
{
typedef C2<sizeof(T)> A;
};
class X : public C<X> { };
Run Code Online (Sandbox Code Playgroud)
两个编译器都拒绝这个,所以我认为它可能不可能,但就像我说我仍然可以在函数内部使用sizeof.我只是希望我不必在每个函数中重复typedef.
template<size_t size> class C2 { };
template<class T>
class C
{
void foo() { typedef C2<sizeof(T)> A; }
};
class X : public C<X> { };
Run Code Online (Sandbox Code Playgroud) 我在模板化的类中遇到了循环依赖的问题.有一个代码示例:
template <typename T> struct A
{
typedef typename T::C D;
//typename T::C c;
};
struct B : public A<B>
{
struct C {};
};
Run Code Online (Sandbox Code Playgroud)
当我尝试实例化B时,我得到一个编译器错误:'C'不是'B'(MSVC)的成员或 无效使用不完整类型'struct B'(GCC).
更改样本以使其工作的最佳方法是什么?
我想确保派生类实现一个特定的静态方法.我认为这样做应该可以使用static_assert,std :: is_same,decltype,CRTP并且可能使用SFINAE.但是,到目前为止,我发现的类似代码非常复杂,似乎我还没有完全理解它使我无法将其用于我的需求.
到目前为止我尝试过的是这个
template <class T>
class Base
{
static_assert(std::is_same<decltype(T::foo(1)), int>::value, "ERROR STRING");
};
class Derived : public Base <Derived>
{
public:
static int foo(int i) { return 42; };
};
Run Code Online (Sandbox Code Playgroud)
但是,它没有编译告诉我,即使方法正确实现,Derived也没有名为foo的元素.此外,在static_assert内的表达式中为foo提供实际参数会感觉不对.
搜索SO揭示了一个类似的问题,最终引导我到这段代码,检查一个类型有方法begin()和end()返回迭代器.所以我试着采用这个代码来满足我的需求.
template <class T>
class Base
{
template<typename C>
static char(&g(typename std::enable_if<std::is_same<decltype(static_cast<int(C::*)(int)>(&C::foo)), int(C::*)(int)>::value, void>::type*))[1];
template<typename C>
static char(&g(...))[2];
static_assert(sizeof(g<T>(0)) == 1, "ERROR STRING");
};
Run Code Online (Sandbox Code Playgroud)
但是这段代码没有编译,因为断言触发了.
所以我的问题是
typename C::const_iterator(C::*)() const示例代码到底意味着什么?是不是一个const函数返回C …我有以下基本模板类.
template<typename T>
class Base {
public:
void do_something() {
}
};
Run Code Online (Sandbox Code Playgroud)
它旨在用作奇怪的重复模板模式.它应该是继承的class B : public Base<B>.它不能像继承一样继承class B : public Base<SomeoneElse>.我想静态地执行这个要求.如果有人使用了这个错误,我预计编译阶段会出错.
我正在做的是把一个static_cast<T const&>(*this)在do_something().这样,继承模板的类是继承自作为模板参数提供的类.抱歉这个令人困惑的表情.用简单的英语,它需要B是或继承SomeoneElse在class B : public Base<SomeoneElse>.
我不知道这是否是实现这一目标的最佳方式.看起来很粗鲁.
但是我想做更多.我想确保B它SomeoneElse本身.我怎样才能做到这一点?
我使用可变参数模板来实现访问者模式:
template<typename... Types>
class Visitor;
template<typename Type>
class Visitor<Type> {
public:
virtual void visit(Type &visitable) = 0;
};
template<typename Type, typename... Types>
class Visitor<Type, Types...>: public Visitor<Types...> {
public:
using Visitor<Types...>::visit;
virtual void visit(Type &visitable) = 0;
};
template<typename... Types>
class VisitableInterface {
public:
virtual void accept(Visitor<Types...> &visitor) = 0;
};
template<typename Derived, typename... Types>
class Visitable : public VisitableInterface<Types...> {
public:
virtual void accept(Visitor<Types...> &visitor) {
visitor.visit(static_cast<Derived&>(*this));
}
};
class IntegerElement;
class StringElement;
class BoxElement;
class ImageElement;
class IntegerElement: …Run Code Online (Sandbox Code Playgroud) 在使用CRTP时,C++ 11/14/17中是否有一种方法可以访问父类中的子类成员?
template <typename T>
class A {
public:
using C = typename std::result_of<decltype(&T::next)(T)>::type;
};
class B : A<B> {
public:
int next() { ... };
};
Run Code Online (Sandbox Code Playgroud)
这应该导致A<B>::C和B::C存在int.
CRTP模式中的基类可以访问派生类的成员函数,但它无法访问派生类中的嵌套类型.
为何如此区别?
为了说明,请考虑以下代码:
template<typename Derived>
struct crtp_base
{
void crtp_method() { return static_cast<Derived&>(*this).method(); } // compiles
using crtp_type = typename Derived::type; // doesn't compile
};
struct X : public crtp_base<X>
{
void method() {}
using type = int;
};
int main()
{
}
Run Code Online (Sandbox Code Playgroud)
crtp_type导致编译错误,虽然crtp_method编译都很好,但两者都试图访问Derived类中定义的内容.什么是解释这种差异的C++规范?
我正在尝试使用CRTP,但我很困惑为什么以下代码无法编译.
template<template<class...> class CBase>
struct ComponentX : public CBase<ComponentX>
{
// This does NOT compile
};
template<template<class...> class CBase>
struct ComponentY : public CBase<int>
{
// This does compile
};
Run Code Online (Sandbox Code Playgroud)
您知道在CRTP的情况下模板模板参数是否有一些限制?
我希望以下代码能够工作:
template <typename Self>
struct foo_base {
auto get(typename Self::type n) { return n; }
};
template <typename T>
struct foo : public foo_base<foo<T>> {
using type = T;
};
Run Code Online (Sandbox Code Playgroud)
问题当然是首先实例化基础,因此您不能引用派生成员类型.我需要在这里进行某种懒惰的评估.
我已经尝试制作功能模板并在其上安装了SFINAE,类似于:
template <typename Self>
struct foo_base {
template <typename T, typename = std::enable_if_t<std::is_same_v<T, typename Self::type>>>
auto get(T n) { return n; }
};
Run Code Online (Sandbox Code Playgroud)
但它似乎不会影响订单.有任何想法吗?
编辑:
解决方案的限制:
struct foo : foo_base<foo<T>, T>或变种.