template<class T>
struct broker
{
typedef T typeBroker;
static std::vector<std::string> extractListBroker(const std::string& broker)
{
std::vector<std::string> vec;
if(broker.empty())
{
for(int i=0;i<typeBroker::nbBroker;++i)
vec.push_back( typeBroker::listBroker[i] );
}
else
{
typedef boost::tokenizer<boost::char_separator<char> > my_tok;
boost::char_separator<char> sep( ";" );
my_tok tok( broker, sep );
for ( my_tok::const_iterator i = tok.begin(); i != tok.end(); ++i )
vec.push_back( *i );
}
return vec;
}
std::string brokerToStr(typename typeBroker::BROKER i) //<--Problem here !!
{
return typeBroker::listBroker[i];
}
};
struct brokerDisTradable : broker<brokerDisTradable>{
std::vector<std::string> listBroker;
brokerDisTradable()
{
listBroker.push_back("BRIDGE1" );
listBroker.push_back("BRIDGELONDON" …
Run Code Online (Sandbox Code Playgroud) 当我看到使用的 CRTP 模式时,似乎在基类型中调用的函数名称总是指向派生类型中不同名称的实现函数(例如:foo()
in base 进行调用static_cast<DerivedType*>(this)->foo_implementation();
.
有没有办法使用相同的函数名来实现 CRTP 模式?我有一个较长的继承链,其中函数可能在链的第一级没有具体实现,因此必须使用不同的函数名称不是很干净/可读。
我想要有如下的东西:
template <typename SecondType>
struct FirstType {
void foo() {
static_cast<SecondType*>(this)->foo();
}
};
template <typename ThirdType>
struct SecondType : FirstType<SecondType> {
void foo() {
static_cast<ThirdType*>(this)->foo();
}
};
struct ThirdType : SecondType<ThirdType> {
void foo() {
// Concrete implementation here
}
};
Run Code Online (Sandbox Code Playgroud)
当然,编译器不会抱怨这一点,但我想它会导致隐式 vtable 查找(尽管关键字virtual
没有出现),从而违背了使用 CRTP 的目的。
我想构建以下类.基类是定义要实现的函数,Derived实现了这个接口.
template <class T, class V>
class IBase
{
public:
virtual void foo(const typename V::t_args&) =0;
};
template<class T>
struct T_args
{
T z;
};
class Derived : public IBase<double, Derived>
{
public:
typedef T_args<double> t_args;
Derived() {}
void foo(const t_args& x)
{ /* do some stuff */ }
};
Run Code Online (Sandbox Code Playgroud)
编译器抱怨Derived是一个不完整的类型; 我无法理解原因.这种类结构是否正确?
我被迫使用c ++ 98进行编码,但我对c ++ 11及更高版本中的任何解决方案感兴趣.
我正在尝试了解 CRTP 和 C++20。基本上,我希望拥有可以访问派生类型的typedef
s 和 的静态继承using
:
template <typename Derived>
class inherit
{
public:
Derived& underlying()
{
return static_cast<Derived&>(*this);
}
Derived const& underlying() const
{
return static_cast<Derived const&>(*this);
}
};
template <typename Derived>
class tester : public inherit<Derived>
{
public:
using value_type = typename Derived::value_type;
};
class real : public tester<real>
{
public:
using value_type = int;
};
int main()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
正如有关 SO 的其他一些问题中 所解释的,从 C++14 开始,这是不允许的(我发现的答案参考该标准和 C++11)。我的理解是,C++17 中也没有办法(如果我的编译器是正确的)。
C++20 目前的状况如何?即将推出的标准是否有更好的解决方案?
在寻找在容器中存储 CRTP 对象的方法时,我发现了以下问题:
\n\n\n\n我尝试了标记的解决方案
\n\n\n\n但编译器抱怨错误如下:
\n\nno known conversion for argument 1 from \xe2\x80\x98std::shared_ptr<DerivedA>\xe2\x80\x99 to \xe2\x80\x98const std::shared_ptr<BaseInterface>&\xe2\x80\x99\n
Run Code Online (Sandbox Code Playgroud)\n\n这是我的尝试:
\n\n#include <vector>\n#include <memory>\n\nstruct BaseInterface {\n virtual ~BaseInterface() {}\n virtual double interface() = 0;\n};\n\ntemplate <typename Derived>\nclass Base : BaseInterface {\npublic:\n double interface(){\n return static_cast<Derived*>(this)->implementation();\n}\n};\n\nclass DerivedA : public Base<DerivedA>{\npublic:\n double implementation(){ return 2.0;}\n};\n\nclass DerivedB : public Base<DerivedB>{\npublic:\n double implementation(){ return 1.0;}\n};\n\n\nint main() {\n std::vector<std::shared_ptr<BaseInterface>> ar;\n ar.emplace_back(std::make_shared<DerivedA>());\nreturn 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n您知道如何修复编译器错误,或者如何更好地解决问题吗?\n提前致谢
\n我想将具有固定签名的待创建函数的名称注入到 CRTP(Curious recurring template pattern)基类中。
这是我现有的工作代码(coliru MCVE 链接):-
#include <iostream>
#include <string>
//--- library layer ---
template<class O,class Under> struct Crtp{
Under* oNo=nullptr;
auto getUnderlying(){
return oNo;
}
};
//--- user layer ex 1 ---
struct B{ // please don't edit this class
int k=0;
};
struct BO : Crtp<BO,B>{
auto getBOUn(){ return Crtp<BO,B>::getUnderlying();}
// some other functions
};
//--- user layer ex 2 ---
struct C{ // please don't edit this class
int kad=0;
}; …
Run Code Online (Sandbox Code Playgroud) P0847提出了对成员函数使用显式参数的可能性this
。
除了该提案带来的其他好处之外,CRTP 还为没有 C、R 甚至 T 的 CRTP带来了巨大的新可能性。
在 C++ 中实现泛型的常见做法clone
是基于 CRTP,例如请参阅此 SO 帖子。
鉴于我们需要clone
(virtual
或者至少表现为虚拟),允许:
Shape* pCopy = pShape->clone(); // get a copy of the correct runtime type
Run Code Online (Sandbox Code Playgroud)
并且鉴于建议不应声明具有显式 this 参数的成员函数virtual
。
是否仍然有办法使用 P0847 来实现具有动态行为且无需 CRTP 的通用克隆?
我想实现一个class Address
,在创建时,将其字段初始化addr
为唯一值.每次创建Address
实例时,该值都必须增加1 .
让我们举个例子.执行以下代码后:
Address x;
Address y;
Run Code Online (Sandbox Code Playgroud)
x.addr
应该是1,而y.addr
应该是2.
为了实现这一点,我想到了奇怪的重复模板模式.它可行吗?此外,是否有更简单的方法来实现相同的行为?
TIA,吉尔
我有一个类Base
从我有两个类,DerivedA
并DerivedB
定义如下.
template <typename Derived>
class Base{
public:
double interface(){
static_cast<Derived*>(this)->implementation();
}
};
class DerivedA : public Base<DerivedA>{
public:
double implementation(){ return 2.0;}
};
class DerivedB : public Base<DerivedB>{
public:
double implementation(){ return 1.0;}
};
Run Code Online (Sandbox Code Playgroud)
简而言之,我正在尝试执行以下操作来维护对象集合,其中一些对象是,其中DerivedA
一些是DerivedB
:
std::vector<std::shared_ptr<Derived>>
Run Code Online (Sandbox Code Playgroud)
这显然是不可能的,因为我现在已经把这个课程Derived
变成了模板课.
有什么办法可以创建/维护多态的对象集合吗?
编辑:不幸的是,一个简单的模板结构不起作用,因为函数implementation
在我的实际程序中被模板化 - 所以那时implementation
必须是模板化的纯虚函数,这是不可能的.请原谅我缺乏解释.
我想为可变参数模板中的每种类型创建一个纯虚拟接口。例如,一个类:
overloads_interface<int,float,bool>
Run Code Online (Sandbox Code Playgroud)
定义了功能:
virtual void overload(const int& arg) = 0
virtual void overload(const float& arg) = 0
virtual void overload(const bool& arg) = 0
Run Code Online (Sandbox Code Playgroud)
如果我将其他类型添加到变量模板中,例如
overloads_interface<int,float,bool, std::string>
Run Code Online (Sandbox Code Playgroud)
它将自动添加重载:
virtual void overload(const std::string& arg) = 0
Run Code Online (Sandbox Code Playgroud)
然后,为了实例化此类,我必须实现这些功能,例如:
class concrete : public overloads_interface<int,float,bool> {
public:
virtual void overload(const int& arg) override { /**handle int**/ }
virtual void overload(const float& arg) override { /**handle float**/ }
virtual void overload(const bool& arg) override { /**handle bool**/ }
};
Run Code Online (Sandbox Code Playgroud)
这是我创建此类的最佳尝试:
template<typename... args>
class overloads_interface { …
Run Code Online (Sandbox Code Playgroud)