C++ 嵌套模板式铸造
我试图找出如何将typecast运算符添加到下面的嵌套类中,以允许main进行编译,但我无法确定需要什么。main中的下一个倒数第二个赋值导致了这个问题。请注意,最后一个赋值使用类型转换使其工作。我怀疑我需要为“add”类定义一个类型转换操作符,但是如何定义呢 很抱歉列出了这么长的清单,但这很简单,因为我知道如何制作它C++ 嵌套模板式铸造,c++,templates,casting,C++,Templates,Casting,我试图找出如何将typecast运算符添加到下面的嵌套类中,以允许main进行编译,但我无法确定需要什么。main中的下一个倒数第二个赋值导致了这个问题。请注意,最后一个赋值使用类型转换使其工作。我怀疑我需要为“add”类定义一个类型转换操作符,但是如何定义呢 很抱歉列出了这么长的清单,但这很简单,因为我知道如何制作它 #include <iostream> using namespace std; template <char I> struct index { };
#include <iostream>
using namespace std;
template <char I> struct index { };
template <char I, char J> struct marker;
// simple class with just a 2 element int array
struct A {
A() { }
A(int i, int j) { a[0] = i; a[1] = j; }
A(const A& x) { a[0] = x(0); a[1] = x(1); }
template<char I, char J>
marker<I,J> operator()(const index<I>&, const index<J>&) {
return marker<I,J>(*this);
}
friend std::ostream& operator<<(std::ostream& os, const A& _A) {
return os << '{' << _A.a[0] << ',' << _A.a[1] << '}';
}
int& operator()(int i) { return a[i]; }
const int& operator()(int i) const { return a[i]; }
private:
int a[2];
};
template <char I, char J>
struct marker {
const int DI;
const int DJ;
marker(A& a) : _A(a), DI(1), DJ(0) { }
marker(A& a, const int i, const int j) : _A(a), DI(i), DJ(j) { }
marker(const marker& m) : _A(m._A), DI(m.DI), DJ(m.DJ) { }
// cast I,J => J,I
operator marker<J,I>() const {
return marker<J,I>(_A, DJ, DI);
}
marker& operator=(const marker& m) {
_A(0) = m(0);
_A(1) = m(1);
return *this;
}
// returns the i'th or (1-i)'th element of _A
int operator()(int i) const {
return _A(i*DI + (1-i)*DJ);
}
template<class LHS, class RHS>
struct add {
const LHS& lhs;
const RHS& rhs;
add(const LHS& l, const RHS& r) : lhs(l), rhs(r) { }
int operator()(int i) const {
return lhs(i) + rhs(i);
}
add< add,marker > operator+(const marker& b) {
return add< add,marker >(*this, b);
}
};
add< marker,marker > operator+(const marker& b) const {
return add< marker,marker >(*this,b);
}
template<class LHS>
void operator=(const add<LHS,marker>& expr) {
_A(0) = expr(0);
_A(1) = expr(1);
}
private:
A& _A;
};
int main() {
index<'i'> i;
index<'j'> j;
A a(1,2), b;
b(i,j) = a(j,i);
cout << b << endl; // "{2,1}"
b(i,j) = a(i,j) + a(j,i);
cout << b << endl; // "{3,3}"
b(i,j) = a(j,i) + a(i,j); // fails to compile
cout << b << endl; // should be "3,3"
b(i,j) = (marker<'i','j'>)a(j,i) + a(i,j); // works fine
cout << b << endl; // "{3,3}"
return 0;
}
#包括
使用名称空间std;
模板结构索引{};
模板结构标记;
//只包含2个元素的int数组的简单类
结构A{
A(){}
A(inti,intj){A[0]=i;A[1]=j;}
A(常数A&x){A[0]=x(0);A[1]=x(1);}
模板
标记运算符()(常数索引和,常数索引和){
返回标记(*此标记);
}
friend std::ostream&operatorclang给出以下错误:
/tmp/webcompile/_13759_1.cc:97:10: error: no viable overloaded '='
b(i,j) = a(j,i) + a(i,j); // fails to compile
~~~~~~ ^ ~~~~~~~~~~~~~~~
/tmp/webcompile/_13759_1.cc:44:11: note: candidate function not viable: no known conversion from 'add<marker<'j', 'i'>, marker<'j', 'i'> >' to 'const marker<'i', 'j'>' for 1st argument;
marker& operator=(const marker& m) {
^
/tmp/webcompile/_13759_1.cc:76:8: note: candidate template ignored: failed template argument deduction
void operator=(const add<LHS,marker>& expr) {
^
编辑:
如果显式调用运算符=并强制使用模板参数,则问题变得更加明显:
/tmp/webcompile/_28787_0.cc:95:10: error: no matching member function for call to 'operator='
b(i,j).operator=<marker<'j', 'i'>, marker<'j', 'i'> >(a(j,i) + a(i,j)); // fails to compile
~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/tmp/webcompile/_28787_0.cc:76:6: note: candidate function [with LHS = marker<'j', 'i'>, RHS = marker<'j', 'i'>] not viable: no known conversion from 'add<marker<'j', 'i'>, marker<'j', 'i'> >' (aka 'marker<'j', 'i'>::add<marker<'j', 'i'>, marker<'j', 'i'> >') to 'add<marker<'j', 'i'>, marker<'j', 'i'> >' (aka 'marker<'i', 'j'>::add<marker<'j', 'i'>, marker<'j', 'i'> >') for 1st argument;
void operator=(add<LHS,RHS>);
^
/tmp/webcompile/\u 28787\u 0.cc:95:10:错误:调用“operator=”时没有匹配的成员函数
运算符=(a(j,i)+a(i,j));//编译失败
~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/tmp/webcompile/_28787_0.cc:76:6:注意:候选函数[带有LHS=marker,RHS=marker]不可行:没有已知的从第一个参数的“add”(又名“marker::add”)到“add”(又名“marker::add”)的转换;
void运算符=(add);
^
具体地说,参数是marker::add
,参数是marker::add
[SOLVED]好的,算出了。我所要做的就是将以下成员添加到类marker中:
template <class LHS>
void operator=(const typename marker<J,I>::template add< LHS, marker<J,I> >& expr) {
myA(0) = expr(1);
myA(1) = expr(0);
}
模板
void运算符=(const typename marker::template add&expr){
myA(0)=表达式(1);
myA(1)=表达式(0);
}
参数规范的语法把我搞糊涂了。它给了我线索,一些尝试和错误使语法正确。这可能不是问题的原因,而是以下划线和大写字母开头的标识符(如\u a
)是的,谢谢。我不知道。虽然在这种情况下,编译器没有抱怨。我想是这样的。你的建议虽然更一般,但也会给出类似的错误。另外,如果你将b(i,j)
更改为b(j,i)
在给出错误的行中,参数变为marker::add
,代码将编译。但是,我想知道解决方案是什么。
template <class LHS>
void operator=(const typename marker<J,I>::template add< LHS, marker<J,I> >& expr) {
myA(0) = expr(1);
myA(1) = expr(0);
}