Sunday, 15 June 2014

templates - Should this bit of C++ CRTP code compile, and if so what should it do? -



templates - Should this bit of C++ CRTP code compile, and if so what should it do? -

i thinking using crtp classes help overloading , wondered next bit of code do:

#include <iostream> #include <typeinfo> template <class tderived> class functionimplementation { }; class abstractfunction { }; class basefunction : public abstractfunction, public functionimplementation<basefunction> { }; class derivedfunction : public basefunction, public functionimplementation<derivedfunction> { }; template <class tderived> void foo(const functionimplementation<tderived>& function) { std::cout << "in foo " << typeid(tderived).name() << std::endl; } int main() { basefunction base; derivedfunction derived; foo(base); foo(derived); }

with gcc 4.2 on os x doesn't compile:

overload.cpp: in function ‘int main()’: overload.cpp:31: error: no matching function phone call ‘foo(derivedfunction&)’

with clang 4.0 on same system, compiles , 'natural' thing when runs:

in foo 12basefunction in foo 15derivedfunction

with visual c++ 2010, compiles runs differently:

in foo class basefunction in foo class basefunction

finally, gcc 4.7.2 on linux not compile gives more finish , authoritative-sounding error message:

overload.cpp: in function ‘int main()’: overload.cpp:31:16: error: no matching function phone call ‘foo(derivedfunction&)’ overload.cpp:31:16: note: candidate is: overload.cpp:22:6: note: template<class tderived> void foo(const functionimplementation<tderived>&) overload.cpp:22:6: note: template argument deduction/substitution failed: overload.cpp:31:16: note: ‘derivedfunction’ ambiguous base of operations class of ‘const functionimplementation<tderived>’

which correct? no expert @ navigating language standard...

in case believe gcc right. asking compiler perform type deduction you, , problem given argument of type derivedfunction not functionimplementation<tderived> directly, conversion has performed. @ point list of conversions includes functionimplementation<basefunction> (through basefunction) , functionimplementation<derivedfunction> (directly). there no ordering among 2 choices, compiler bails out ambiguity.

the standard treats in §14.8.2.1 [temp.deduct.call]/4,5

(paragraph 4) in general, deduction process attempts find template argument values create deduced identical (after type transformed described above). however, there 3 cases allow difference:

[...]

if p class , p has form simple-template-id, transformed can derived class of deduced a. likewise, if p pointer class of form simple-template-id, transformed can pointer derived class pointed deduced a.

(paragraph 5) these alternatives considered if type deduction otherwise fail. if yield more 1 possible deduced a, type deduction fails.

in 4th paragraph allows type deduction pick base of operations of argument type, in case there 2 such bases. 5th paragraph determines if application of previous rule yields more 1 result, type deduction fails.

c++ templates inheritance method-overloading crtp

No comments:

Post a Comment