我知道这似乎很复杂,但我希望有人可以在这里指出我的错误。我确信这个设计会让你的嘴巴有些不好,我很高兴听到设计方案。但表格来自问题领域的建模。
我确定我很傻,但是模板与继承相结合的方式让我很困惑。以下是一些简化代码,其中包含以下说明:
// main.cpp
#include <cstdio>
template <typename POD>
class A {
public:
POD data;
POD get_a() { return data; }
};
template <typename T>
class B {
public:
virtual void do_something_with_an_A_child(const T&) = 0;
};
class ADerived : public A<float> {
public:
ADerived(float a) { data = a; }
};
class BDerived : public B<ADerived> {
public:
virtual void do_something_with_an_A_child(const ADerived& someA) {
printf("A bit of A-type's data: %f\n", someA.data);
}
};
template <typename POD>
class Aggregator {
public:
A<POD>* instanceOfA;
B<A<POD>>* instanceOfB;
Aggregator(A<POD>* anA, B<A<POD>>* aB) : instanceOfA(anA), instanceOfB(aB) {}
};
int main() {
ADerived myADerived(3.14159f);
BDerived myBDerived;
Aggregator<float> myAggregator(&myADerived, &myBDerived);
return 1;
}
所以A
是一个类模板,其签名只是一些内置类型。 (在我的特定情况下,A
具有对其内部数据进行操作的方法。)类B
旨在承诺某些操作的接口,这些操作适用于{{1}的特定实例}。因此,在上面的代码中,您看到我将A<.>
和A
定义为模板类,然后创建继承自这些模板类的类,并提供B
和ADerived
。< / p>
(在实际情况中,BDerived
表示数学模型和一些数据,A
是用于对模型执行数学优化的接口。)
现在,一个应该链接到B
和ADerivded
实例的类(为了创建基于其接口的通用算法)我调用了BDerived
,只需在构造函数中获取一些指针。我只希望Aggregator
需要知道Aggregator
类型,因为它只是为了操纵接口而不是太担心对象包含的内容。
我从POD
clang++
收到以下编译错误:
-std=c++14
含义很明确,但我不确定为什么它看不到main.cpp:42:21: error: no matching constructor for initialization of 'Aggregator<float>'
Aggregator<float> myAggregator(&myADerived, &myBDerived);
^ ~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:35:3: note: candidate constructor not viable: no known conversion from 'BDerived *' to 'B<A<float> > *' for 2nd argument
Aggregator(A<POD>* anA, B<A<POD>>* aB) : instanceOfA(anA), instanceOfB(aB) {}
^
是BDerived
。我的意思是,它具体是B<A<float>>
,但B<ADerived>
是ADerived
,因此A<float>
应该被视为BDerived
。这显然不是这样,所以要么我做了一些愚蠢的事情,希望有人指出它,或者这在C ++中是不可能的,我需要一些替代的设计建议。
答案 0 :(得分:2)
模板参数以静态方式和精确类型解析。因此即使B<ADerived>
是B<A<POD>>
的后代,ADerived
也不会衰减到A<POD>
。您可以通过以下方式解决此问题:
T
中再添加一个模板参数Aggregator
,并可选择确保{使用std::enable_if<>
和std::is_base<>
)A<POD>
是T
的基础{1}}或T
在B
中公开typedef
,然后在T
中取Aggregator
并将T
和A<B::T>
存储在Aggregator
中public class Print2ndChar {
public static void main(String[] args) throws java.lang.Exception {
Print2ndChar mainObj = new Print2ndChar();
java.io.BufferedReader inputReader = new java.io.BufferedReader(new java.io.InputStreamReader(System.in));
String noOfTestCase;
if(((noOfTestCase = inputReader.readLine()) == null))
System.exit(0);
int noOfLines = 0;
try{
noOfLines = Integer.parseInt(noOfTestCase);
}catch(Exception e){
System.exit(0);
}
if(noOfLines<0 || noOfLines>100)
System.exit(0);
String [] randomWords = new String[noOfLines];
for(int i=0;i<noOfLines;i++){
randomWords[i] = inputReader.readLine();
if(randomWords[i] == null || randomWords[i].length()<2 || randomWords[i].length()%2!=0 || (randomWords[i].length()/2)>100)
System.exit(0);
}
for (String word : randomWords){
mainObj.letsBegin(word.substring(0, word.length() / 2));
System.out.println();
}
}
private void letsBegin(String data) {
if (data.length() <= 0) {
return;
} else {
System.out.print(data.charAt(0));
if (data.length() >= 3)
letsBegin(data.substring(2, data.length()));
}
}
}
。