我想在一个地方知道这三个概念的确切而简洁的定义.答案的质量应取决于以下两点.
注意:
可能有许多正确的答案,因为每个概念都有许多不同的方面.如果有很多好的答案,我最终会将问题转化为CW并汇总答案.
- 发布接受编辑 -
c++ templates components metaprogramming generic-programming
基本上我只想使用任意类型的给定参数进行任意操作.
参数类型基类是Var,而Operation是将为给定参数执行的操作的基类.
我有Evaluator类,它包含使用opId映射的运算符集合.Evaluator将根据evaluate()成员函数中给出的opId参数进行操作,然后evaluate()函数将搜索将接受参数类型和opId的受支持运算符.
我想问的是,有没有有效的模式或算法可以在没有dynamic_cast <>和/或循环运算符集合的情况下执行此操作.
`
class Var {
public:
bool isValidVar();
static Var invalidVar();
}
template<typename T> class VarT : public Var {
public:
virtual const T getValue() const;
}
class Operator {
public:
virtual Var evaluate(const Var& a, const Var& b) = 0;
}
template<typename T> class AddOperator : public Operator {
public:
virtual Var evaluate(const Var& a, const Var& b)
{ //dynamic_cast is slow!
const VarT<T>* varA = dynamic_cast<const VarT<T>*>(&a);
const …Run Code Online (Sandbox Code Playgroud) 假设您有一些目标类,其中包含一些方法:
class Subject
{
public:
void voidReturn() { std::cout<<__FUNCTION__<<std::endl; }
int intReturn() { std::cout<<__FUNCTION__<<std::endl; return 137; }
};
Run Code Online (Sandbox Code Playgroud)
和Value类(概念类似于Boost.Any):
struct Value
{
Value() {}
Value( Value const & orig ) {}
template< typename T > Value( T const & val ) {}
};
Run Code Online (Sandbox Code Playgroud)
我想使用Subject类中的方法生成一个Value对象:
Subject subject;
Value intval( subject.intReturn() );
Value voidVal( subject.voidReturn() ); // compilation error
Run Code Online (Sandbox Code Playgroud)
我在VC++ 2008中遇到以下错误:
error C2664: 'Value::Value(const Value &)' : cannot convert parameter 1 from 'void' to 'const Value &'
Expressions of type void cannot …Run Code Online (Sandbox Code Playgroud) 我有一个问题(可能是由于我对C#泛型缺乏熟悉)来获取非封闭类型的泛型.除了正在使用的显式验证器接口之外,我有几个看起来与以下内容非常类似的方法.
public IEnumerable<IDeleteValidator<T>> GetDeleteValidators<T>()
{
var validatorList = new List<IDeleteValidator<T>>();
foreach (var type in GetRecursiveBaseTypesAndInterfaces(typeof(T)))
{
var validatorType = typeof(IDeleteValidator<>).MakeGenericType(type);
var validators = ObjectFactory
.GetAllInstances(validatorType).Cast<IDeleteValidator<T>>();
validatorList.AddRange(validators);
}
return validatorList;
}
Run Code Online (Sandbox Code Playgroud)
方法GetRecursiveBaseTypesAndInterfaces按照说法执行,并收集给定类型的所有基类型和接口.所以我最终要做的是获取显式验证器接口的未闭合类型,并在每个原始类型T的基类和接口上将其类型关闭.这很好用,但是我想清理我的代码并以比上面更通用的形式完成它
知道T的任何验证器将扩展IValidator(如下)
public interface IDeleteValidator<in T> : IValidator<T> {}
Run Code Online (Sandbox Code Playgroud)
我对上述方法的泛型版本的未完成尝试如下:
public IEnumerable<TValidator> GetValidators<T, TValidator>()
where TValidator : IValidator<T>
{
var validatorList = new List<TValidator>();
foreach (var type in GetRecursiveBaseTypesAndInterfaces(typeof(T)))
{
var unclosedType = ???
var validatorType = typeof(unclosedType).MakeGenericType(type);
var validators = ObjectFactory
.GetAllInstances(validatorType).Cast<TValidator>();
validatorList.AddRange(validators);
}
return validatorList;
} …Run Code Online (Sandbox Code Playgroud) 泛型类型的深层副本(克隆)如何T, E在Java中工作?可能吗?
E oldItem;
E newItem = olditem.clone(); // does not work
Run Code Online (Sandbox Code Playgroud) 我有一堆具有一个共同功能的类,除了它返回一个指向它们自己类型的指针.代码看起来一样,我想把它移到一个抽象的基类中.但是,我怎样才能使从它继承的类返回自己的类型?
class base {
base *foo() {
// ...
}
};
class derived : public base {
};
derived d;
d.foo(); // Should return derived* instead of base*
Run Code Online (Sandbox Code Playgroud)
有没有办法用C++表达这个?
我认为类型签名看起来像f :: a -> [Int]
输入数据data NamedPoint = NamedPoint String Int Int
data Person = Name Int Int Int
Run Code Online (Sandbox Code Playgroud)
在REPL中使用它看起来像这样:
>> let namedPoint = NamedPoint "hey" 1 2
>> let tommy = Person "Tommy" 1 2 3
>> f namedPoint
>> [1,2]
>> f Tommy
>> [1,2,3]
Run Code Online (Sandbox Code Playgroud)
我认为这对于记录的替代方法很有用,因为当你懒得为具有大量参数的数据编写getter时.
我有一个代码:
class Client2ServerProtocol {
};
class ProtocolHelper {
public:
template<class ProtocolClass>
int GetProtocolId() {
return -1;
}
};
template<> inline int
ProtocolHelper::GetProtocolId<Client2ServerProtocol>() {
return 1;
}
template<typename PROTOCOL_HELPER>
class Dispatcher {
public:
template<typename PROTOCOL_CLASS>
void Subscribe(int msgId) {
int protoId = helper.GetProtocolId<PROTOCOL_CLASS>();
printf("Subscribe protoId %d, msgId %d", protoId, msgId);
}
PROTOCOL_HELPER helper;
};
int main() {
Dispatcher<ProtocolHelper> dispatcher;
dispatcher.Subscribe<Client2ServerProtocol>(1);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它在MSVC下成功编译(和工作),但是gcc抱怨语法无效:
test.cc:23:56:错误:在'>'之前预期的primary-expression标志int protoId = helper.GetProtocolId();
test.cc:23:58:错误:')'令牌之前的预期primary-expression
我做错了什么?int protoId = helper.GetProtocolId();
我有这样的数据类型:
data MyType = Foo Bool
| Bar
| Baz Bool (Maybe String) Bool
| Quux Int String
Run Code Online (Sandbox Code Playgroud)
我可以使用泛型来编写一个getBools :: MyType -> [Bool]返回输入中所有布尔字段列表的函数吗?
我想出了这种类型的签名:
getAllOfType ::
(Generic inner, Generic outer, HasDatatypeInfo inner, All2 HasDatatypeInfo (Code outer)) =>
Proxy inner -> outer -> [inner]
Run Code Online (Sandbox Code Playgroud)
使用generics-sop,但我不认为这是对的.比较DatatypeInfos不会说服类型检查器这两种类型是等价的.
我正在尝试构造某种"泛型类型别名",这意味着我想要定义一个类型int,例如,但是使用泛型类型参数,然后使其与其他类型的实例不兼容.
我尝试使用别名模板执行此操作:
template <typename T>
using NumberWithSemantics = int;
Run Code Online (Sandbox Code Playgroud)
但问题是所有实例化,无论类型如何T,都被认为是相同的,例如:
struct A {};
struct B {};
NumberWithSemantics<A> getThing() {
return 14;
}
int processDifferentThing(NumberWithSemantics<B> b) {
return b * 3;
}
int main() {
auto a = getThing();
return processDifferentThing(a); // unfortunately compiles just fine
}
Run Code Online (Sandbox Code Playgroud)
有没有办法定义某种不允许混合不同模板实例的泛型类型别名?
c++ ×6
templates ×4
generics ×2
haskell ×2
c# ×1
c++11 ×1
c++17 ×1
clone ×1
components ×1
dynamic-cast ×1
inheritance ×1
java ×1
return-type ×1
type-alias ×1