Template deduction complaints ambiguous candidates
I intend to implement the multiplication operator of my "Sparse Vector" and "Vector" classes. The following simplified code demo shows my problem
The Vector class in Vector.hpp
#pragma once
template <typename T>
class Vector
public:
Vector()
template <typename Scalar>
friend Vector operator*(const Scalar &a, const Vector &rhs) // #1
return Vector();
;
The Sparse Vector class in SpVec.hpp
#pragma once
#include "Vector.hpp"
template <typename T>
class SpVec
public:
SpVec()
template <typename U>
inline friend double operator*(const SpVec &spv, const Vector<U> &v) // #2
return 0.0;
;
The test code in main.cpp:
#include "Vector.hpp"
#include "SpVec.hpp"
#include <iostream>
int main()
Vector<double> v;
SpVec<double> spv;
std::cout << spv * v;
return 0;
I build the test program with
g++ main.cpp -o test
which gives the ambiguous template deduction error
main.cpp: In function ‘int main()’:
main.cpp:13:26: error: ambiguous overload for ‘operator*’ (operand types are ‘SpVec<double>’ and ‘Vector<double>’)
std::cout << spv * v;
~~~~^~~
In file included from main.cpp:2:0:
SpVec.hpp:12:26: note: candidate: double operator*(const SpVec<T>&, const Vector<U>&) [with U = double; T = double]
inline friend double operator*(const SpVec &spv, const Vector<U> &v) // #2
^~~~~~~~
In file included from main.cpp:1:0:
Vector.hpp:10:19: note: candidate: Vector<T> operator*(const Scalar&, const Vector<T>&) [with Scalar = SpVec<double>; T = double]
friend Vector operator*(const Scalar &a, const Vector &rhs) // #1
I expect the #2
method definition is more close to my calling.
Please help me understand how the ambiguous error comes out and how to resolve the issue.
c++ templates metaprogramming ambiguous
add a comment |
I intend to implement the multiplication operator of my "Sparse Vector" and "Vector" classes. The following simplified code demo shows my problem
The Vector class in Vector.hpp
#pragma once
template <typename T>
class Vector
public:
Vector()
template <typename Scalar>
friend Vector operator*(const Scalar &a, const Vector &rhs) // #1
return Vector();
;
The Sparse Vector class in SpVec.hpp
#pragma once
#include "Vector.hpp"
template <typename T>
class SpVec
public:
SpVec()
template <typename U>
inline friend double operator*(const SpVec &spv, const Vector<U> &v) // #2
return 0.0;
;
The test code in main.cpp:
#include "Vector.hpp"
#include "SpVec.hpp"
#include <iostream>
int main()
Vector<double> v;
SpVec<double> spv;
std::cout << spv * v;
return 0;
I build the test program with
g++ main.cpp -o test
which gives the ambiguous template deduction error
main.cpp: In function ‘int main()’:
main.cpp:13:26: error: ambiguous overload for ‘operator*’ (operand types are ‘SpVec<double>’ and ‘Vector<double>’)
std::cout << spv * v;
~~~~^~~
In file included from main.cpp:2:0:
SpVec.hpp:12:26: note: candidate: double operator*(const SpVec<T>&, const Vector<U>&) [with U = double; T = double]
inline friend double operator*(const SpVec &spv, const Vector<U> &v) // #2
^~~~~~~~
In file included from main.cpp:1:0:
Vector.hpp:10:19: note: candidate: Vector<T> operator*(const Scalar&, const Vector<T>&) [with Scalar = SpVec<double>; T = double]
friend Vector operator*(const Scalar &a, const Vector &rhs) // #1
I expect the #2
method definition is more close to my calling.
Please help me understand how the ambiguous error comes out and how to resolve the issue.
c++ templates metaprogramming ambiguous
add a comment |
I intend to implement the multiplication operator of my "Sparse Vector" and "Vector" classes. The following simplified code demo shows my problem
The Vector class in Vector.hpp
#pragma once
template <typename T>
class Vector
public:
Vector()
template <typename Scalar>
friend Vector operator*(const Scalar &a, const Vector &rhs) // #1
return Vector();
;
The Sparse Vector class in SpVec.hpp
#pragma once
#include "Vector.hpp"
template <typename T>
class SpVec
public:
SpVec()
template <typename U>
inline friend double operator*(const SpVec &spv, const Vector<U> &v) // #2
return 0.0;
;
The test code in main.cpp:
#include "Vector.hpp"
#include "SpVec.hpp"
#include <iostream>
int main()
Vector<double> v;
SpVec<double> spv;
std::cout << spv * v;
return 0;
I build the test program with
g++ main.cpp -o test
which gives the ambiguous template deduction error
main.cpp: In function ‘int main()’:
main.cpp:13:26: error: ambiguous overload for ‘operator*’ (operand types are ‘SpVec<double>’ and ‘Vector<double>’)
std::cout << spv * v;
~~~~^~~
In file included from main.cpp:2:0:
SpVec.hpp:12:26: note: candidate: double operator*(const SpVec<T>&, const Vector<U>&) [with U = double; T = double]
inline friend double operator*(const SpVec &spv, const Vector<U> &v) // #2
^~~~~~~~
In file included from main.cpp:1:0:
Vector.hpp:10:19: note: candidate: Vector<T> operator*(const Scalar&, const Vector<T>&) [with Scalar = SpVec<double>; T = double]
friend Vector operator*(const Scalar &a, const Vector &rhs) // #1
I expect the #2
method definition is more close to my calling.
Please help me understand how the ambiguous error comes out and how to resolve the issue.
c++ templates metaprogramming ambiguous
I intend to implement the multiplication operator of my "Sparse Vector" and "Vector" classes. The following simplified code demo shows my problem
The Vector class in Vector.hpp
#pragma once
template <typename T>
class Vector
public:
Vector()
template <typename Scalar>
friend Vector operator*(const Scalar &a, const Vector &rhs) // #1
return Vector();
;
The Sparse Vector class in SpVec.hpp
#pragma once
#include "Vector.hpp"
template <typename T>
class SpVec
public:
SpVec()
template <typename U>
inline friend double operator*(const SpVec &spv, const Vector<U> &v) // #2
return 0.0;
;
The test code in main.cpp:
#include "Vector.hpp"
#include "SpVec.hpp"
#include <iostream>
int main()
Vector<double> v;
SpVec<double> spv;
std::cout << spv * v;
return 0;
I build the test program with
g++ main.cpp -o test
which gives the ambiguous template deduction error
main.cpp: In function ‘int main()’:
main.cpp:13:26: error: ambiguous overload for ‘operator*’ (operand types are ‘SpVec<double>’ and ‘Vector<double>’)
std::cout << spv * v;
~~~~^~~
In file included from main.cpp:2:0:
SpVec.hpp:12:26: note: candidate: double operator*(const SpVec<T>&, const Vector<U>&) [with U = double; T = double]
inline friend double operator*(const SpVec &spv, const Vector<U> &v) // #2
^~~~~~~~
In file included from main.cpp:1:0:
Vector.hpp:10:19: note: candidate: Vector<T> operator*(const Scalar&, const Vector<T>&) [with Scalar = SpVec<double>; T = double]
friend Vector operator*(const Scalar &a, const Vector &rhs) // #1
I expect the #2
method definition is more close to my calling.
Please help me understand how the ambiguous error comes out and how to resolve the issue.
c++ templates metaprogramming ambiguous
c++ templates metaprogramming ambiguous
asked Nov 13 '18 at 5:58
RubinRubin
1037
1037
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
I come up with another idea that the prior type information Scalar
can be used with the SFAINE feature enabled by the c++11
standard library struct std::enable_if
.
The codes:
Vector.hpp
#pragma once
#include <iostream>
#include <type_traits>
template <typename T>
class Vector
public:
Vector()
template <typename Scalar>
typename std::enable_if<std::is_arithmetic<Scalar>::value, Vector<T>>::type
operator*(const Scalar &rhs) const// #1
std::cout << "Vector * Scalar called." << std::endl;
return Vector();
template <typename Scalar>
inline friend typename std::enable_if<std::is_arithmetic<Scalar>::value, Vector<T>>::type
operator*(const Scalar &lhs, const Vector &rhs)
std::cout << "Scalar * Vector called." << std::endl;
return Vector();
;
SpVec.hpp
#pragma once
#include "Vector.hpp"
#include <iostream>
template <typename T>
class SpVec
public:
SpVec()
template <typename U>
inline double operator*(const Vector<U> &rhs) const // #2 as member function
std::cout << "SpVec * Vector called" << std::endl;
return 0.0;
template <typename U>
inline friend double operator*(const Vector<U> &lhs, const SpVec &rhs)
std::cout << "Vector * SpVec called" << std::endl;
return 0.0;
;
main.cpp
#include "SpVec.hpp"
#include "Vector.hpp"
#include <iostream>
int main()
Vector<double> v;
SpVec<double> spv;
double a = spv * v;
a = v * spv;
Vector<double> vt;
vt = v * 2.0;
vt = 2.0 * v;
return 0;
Build the program with c++11
g++ -std=c++11 main.cpp -o test
The result:
SpVec * Vector called.
Vector * SpVec called.
Vector * Scalar called.
Scalar * Vector called.
That's also a nice one !
– Christophe
Nov 13 '18 at 8:34
add a comment |
The argument to operator*
are SpVec<double>
and Vector<double>
. It could be resolved to
operator*(const Scalar &a, const Vector &rhs)
with scalar
as SpVec<double>
and rhs
as Vector<double>
.
It could also resolve to
operator*(const SpVec &spv, const Vector<U> &v)
with spv as SpVec<double>
and U
as double
.
One way of resolving this is to turn Vector::operator*
to non-friend function.
Vector operator*(const Scalar &a) // #1
//The other argument here will be accessed using this pointer.
return Vector();
and you can call it as
int main()
Vector<double> v;
SpVec<double> spv;
std::cout << spv * v; // will call #2
v * spv; //will call #1
return 0;
You beat me to it!
– Francis Cugler
Nov 13 '18 at 6:47
Thanks. This suggestion does work. For the deeper discussion, is it possible to make the two cases both work as no operands precedence need to be cared about for the user?
– Rubin
Nov 13 '18 at 6:57
Nice answer. However, this works only because you play with the order of the parameters (with an operator that is assumed to be commutative).
– Christophe
Nov 13 '18 at 7:06
@Rubin I think the term you are looking for is commutate and not precedence. The commutative property says thata*b
is equal tob*a
. Precedence is used to decide in which order several operators are executed:a + b * c
where multiplication has a higher precedence and will be calculated before the addition. Also here a link to a question about commutative property in the non-templated case: stackoverflow.com/questions/3764604/…
– Philipp
Nov 13 '18 at 7:41
@Philipp Thanks for the correction. The commutative property is indeed what I need.
– Rubin
Nov 13 '18 at 7:49
|
show 2 more comments
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53274692%2ftemplate-deduction-complaints-ambiguous-candidates%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
I come up with another idea that the prior type information Scalar
can be used with the SFAINE feature enabled by the c++11
standard library struct std::enable_if
.
The codes:
Vector.hpp
#pragma once
#include <iostream>
#include <type_traits>
template <typename T>
class Vector
public:
Vector()
template <typename Scalar>
typename std::enable_if<std::is_arithmetic<Scalar>::value, Vector<T>>::type
operator*(const Scalar &rhs) const// #1
std::cout << "Vector * Scalar called." << std::endl;
return Vector();
template <typename Scalar>
inline friend typename std::enable_if<std::is_arithmetic<Scalar>::value, Vector<T>>::type
operator*(const Scalar &lhs, const Vector &rhs)
std::cout << "Scalar * Vector called." << std::endl;
return Vector();
;
SpVec.hpp
#pragma once
#include "Vector.hpp"
#include <iostream>
template <typename T>
class SpVec
public:
SpVec()
template <typename U>
inline double operator*(const Vector<U> &rhs) const // #2 as member function
std::cout << "SpVec * Vector called" << std::endl;
return 0.0;
template <typename U>
inline friend double operator*(const Vector<U> &lhs, const SpVec &rhs)
std::cout << "Vector * SpVec called" << std::endl;
return 0.0;
;
main.cpp
#include "SpVec.hpp"
#include "Vector.hpp"
#include <iostream>
int main()
Vector<double> v;
SpVec<double> spv;
double a = spv * v;
a = v * spv;
Vector<double> vt;
vt = v * 2.0;
vt = 2.0 * v;
return 0;
Build the program with c++11
g++ -std=c++11 main.cpp -o test
The result:
SpVec * Vector called.
Vector * SpVec called.
Vector * Scalar called.
Scalar * Vector called.
That's also a nice one !
– Christophe
Nov 13 '18 at 8:34
add a comment |
I come up with another idea that the prior type information Scalar
can be used with the SFAINE feature enabled by the c++11
standard library struct std::enable_if
.
The codes:
Vector.hpp
#pragma once
#include <iostream>
#include <type_traits>
template <typename T>
class Vector
public:
Vector()
template <typename Scalar>
typename std::enable_if<std::is_arithmetic<Scalar>::value, Vector<T>>::type
operator*(const Scalar &rhs) const// #1
std::cout << "Vector * Scalar called." << std::endl;
return Vector();
template <typename Scalar>
inline friend typename std::enable_if<std::is_arithmetic<Scalar>::value, Vector<T>>::type
operator*(const Scalar &lhs, const Vector &rhs)
std::cout << "Scalar * Vector called." << std::endl;
return Vector();
;
SpVec.hpp
#pragma once
#include "Vector.hpp"
#include <iostream>
template <typename T>
class SpVec
public:
SpVec()
template <typename U>
inline double operator*(const Vector<U> &rhs) const // #2 as member function
std::cout << "SpVec * Vector called" << std::endl;
return 0.0;
template <typename U>
inline friend double operator*(const Vector<U> &lhs, const SpVec &rhs)
std::cout << "Vector * SpVec called" << std::endl;
return 0.0;
;
main.cpp
#include "SpVec.hpp"
#include "Vector.hpp"
#include <iostream>
int main()
Vector<double> v;
SpVec<double> spv;
double a = spv * v;
a = v * spv;
Vector<double> vt;
vt = v * 2.0;
vt = 2.0 * v;
return 0;
Build the program with c++11
g++ -std=c++11 main.cpp -o test
The result:
SpVec * Vector called.
Vector * SpVec called.
Vector * Scalar called.
Scalar * Vector called.
That's also a nice one !
– Christophe
Nov 13 '18 at 8:34
add a comment |
I come up with another idea that the prior type information Scalar
can be used with the SFAINE feature enabled by the c++11
standard library struct std::enable_if
.
The codes:
Vector.hpp
#pragma once
#include <iostream>
#include <type_traits>
template <typename T>
class Vector
public:
Vector()
template <typename Scalar>
typename std::enable_if<std::is_arithmetic<Scalar>::value, Vector<T>>::type
operator*(const Scalar &rhs) const// #1
std::cout << "Vector * Scalar called." << std::endl;
return Vector();
template <typename Scalar>
inline friend typename std::enable_if<std::is_arithmetic<Scalar>::value, Vector<T>>::type
operator*(const Scalar &lhs, const Vector &rhs)
std::cout << "Scalar * Vector called." << std::endl;
return Vector();
;
SpVec.hpp
#pragma once
#include "Vector.hpp"
#include <iostream>
template <typename T>
class SpVec
public:
SpVec()
template <typename U>
inline double operator*(const Vector<U> &rhs) const // #2 as member function
std::cout << "SpVec * Vector called" << std::endl;
return 0.0;
template <typename U>
inline friend double operator*(const Vector<U> &lhs, const SpVec &rhs)
std::cout << "Vector * SpVec called" << std::endl;
return 0.0;
;
main.cpp
#include "SpVec.hpp"
#include "Vector.hpp"
#include <iostream>
int main()
Vector<double> v;
SpVec<double> spv;
double a = spv * v;
a = v * spv;
Vector<double> vt;
vt = v * 2.0;
vt = 2.0 * v;
return 0;
Build the program with c++11
g++ -std=c++11 main.cpp -o test
The result:
SpVec * Vector called.
Vector * SpVec called.
Vector * Scalar called.
Scalar * Vector called.
I come up with another idea that the prior type information Scalar
can be used with the SFAINE feature enabled by the c++11
standard library struct std::enable_if
.
The codes:
Vector.hpp
#pragma once
#include <iostream>
#include <type_traits>
template <typename T>
class Vector
public:
Vector()
template <typename Scalar>
typename std::enable_if<std::is_arithmetic<Scalar>::value, Vector<T>>::type
operator*(const Scalar &rhs) const// #1
std::cout << "Vector * Scalar called." << std::endl;
return Vector();
template <typename Scalar>
inline friend typename std::enable_if<std::is_arithmetic<Scalar>::value, Vector<T>>::type
operator*(const Scalar &lhs, const Vector &rhs)
std::cout << "Scalar * Vector called." << std::endl;
return Vector();
;
SpVec.hpp
#pragma once
#include "Vector.hpp"
#include <iostream>
template <typename T>
class SpVec
public:
SpVec()
template <typename U>
inline double operator*(const Vector<U> &rhs) const // #2 as member function
std::cout << "SpVec * Vector called" << std::endl;
return 0.0;
template <typename U>
inline friend double operator*(const Vector<U> &lhs, const SpVec &rhs)
std::cout << "Vector * SpVec called" << std::endl;
return 0.0;
;
main.cpp
#include "SpVec.hpp"
#include "Vector.hpp"
#include <iostream>
int main()
Vector<double> v;
SpVec<double> spv;
double a = spv * v;
a = v * spv;
Vector<double> vt;
vt = v * 2.0;
vt = 2.0 * v;
return 0;
Build the program with c++11
g++ -std=c++11 main.cpp -o test
The result:
SpVec * Vector called.
Vector * SpVec called.
Vector * Scalar called.
Scalar * Vector called.
edited Nov 13 '18 at 11:14
Oliv
9,2171957
9,2171957
answered Nov 13 '18 at 8:30
RubinRubin
1037
1037
That's also a nice one !
– Christophe
Nov 13 '18 at 8:34
add a comment |
That's also a nice one !
– Christophe
Nov 13 '18 at 8:34
That's also a nice one !
– Christophe
Nov 13 '18 at 8:34
That's also a nice one !
– Christophe
Nov 13 '18 at 8:34
add a comment |
The argument to operator*
are SpVec<double>
and Vector<double>
. It could be resolved to
operator*(const Scalar &a, const Vector &rhs)
with scalar
as SpVec<double>
and rhs
as Vector<double>
.
It could also resolve to
operator*(const SpVec &spv, const Vector<U> &v)
with spv as SpVec<double>
and U
as double
.
One way of resolving this is to turn Vector::operator*
to non-friend function.
Vector operator*(const Scalar &a) // #1
//The other argument here will be accessed using this pointer.
return Vector();
and you can call it as
int main()
Vector<double> v;
SpVec<double> spv;
std::cout << spv * v; // will call #2
v * spv; //will call #1
return 0;
You beat me to it!
– Francis Cugler
Nov 13 '18 at 6:47
Thanks. This suggestion does work. For the deeper discussion, is it possible to make the two cases both work as no operands precedence need to be cared about for the user?
– Rubin
Nov 13 '18 at 6:57
Nice answer. However, this works only because you play with the order of the parameters (with an operator that is assumed to be commutative).
– Christophe
Nov 13 '18 at 7:06
@Rubin I think the term you are looking for is commutate and not precedence. The commutative property says thata*b
is equal tob*a
. Precedence is used to decide in which order several operators are executed:a + b * c
where multiplication has a higher precedence and will be calculated before the addition. Also here a link to a question about commutative property in the non-templated case: stackoverflow.com/questions/3764604/…
– Philipp
Nov 13 '18 at 7:41
@Philipp Thanks for the correction. The commutative property is indeed what I need.
– Rubin
Nov 13 '18 at 7:49
|
show 2 more comments
The argument to operator*
are SpVec<double>
and Vector<double>
. It could be resolved to
operator*(const Scalar &a, const Vector &rhs)
with scalar
as SpVec<double>
and rhs
as Vector<double>
.
It could also resolve to
operator*(const SpVec &spv, const Vector<U> &v)
with spv as SpVec<double>
and U
as double
.
One way of resolving this is to turn Vector::operator*
to non-friend function.
Vector operator*(const Scalar &a) // #1
//The other argument here will be accessed using this pointer.
return Vector();
and you can call it as
int main()
Vector<double> v;
SpVec<double> spv;
std::cout << spv * v; // will call #2
v * spv; //will call #1
return 0;
You beat me to it!
– Francis Cugler
Nov 13 '18 at 6:47
Thanks. This suggestion does work. For the deeper discussion, is it possible to make the two cases both work as no operands precedence need to be cared about for the user?
– Rubin
Nov 13 '18 at 6:57
Nice answer. However, this works only because you play with the order of the parameters (with an operator that is assumed to be commutative).
– Christophe
Nov 13 '18 at 7:06
@Rubin I think the term you are looking for is commutate and not precedence. The commutative property says thata*b
is equal tob*a
. Precedence is used to decide in which order several operators are executed:a + b * c
where multiplication has a higher precedence and will be calculated before the addition. Also here a link to a question about commutative property in the non-templated case: stackoverflow.com/questions/3764604/…
– Philipp
Nov 13 '18 at 7:41
@Philipp Thanks for the correction. The commutative property is indeed what I need.
– Rubin
Nov 13 '18 at 7:49
|
show 2 more comments
The argument to operator*
are SpVec<double>
and Vector<double>
. It could be resolved to
operator*(const Scalar &a, const Vector &rhs)
with scalar
as SpVec<double>
and rhs
as Vector<double>
.
It could also resolve to
operator*(const SpVec &spv, const Vector<U> &v)
with spv as SpVec<double>
and U
as double
.
One way of resolving this is to turn Vector::operator*
to non-friend function.
Vector operator*(const Scalar &a) // #1
//The other argument here will be accessed using this pointer.
return Vector();
and you can call it as
int main()
Vector<double> v;
SpVec<double> spv;
std::cout << spv * v; // will call #2
v * spv; //will call #1
return 0;
The argument to operator*
are SpVec<double>
and Vector<double>
. It could be resolved to
operator*(const Scalar &a, const Vector &rhs)
with scalar
as SpVec<double>
and rhs
as Vector<double>
.
It could also resolve to
operator*(const SpVec &spv, const Vector<U> &v)
with spv as SpVec<double>
and U
as double
.
One way of resolving this is to turn Vector::operator*
to non-friend function.
Vector operator*(const Scalar &a) // #1
//The other argument here will be accessed using this pointer.
return Vector();
and you can call it as
int main()
Vector<double> v;
SpVec<double> spv;
std::cout << spv * v; // will call #2
v * spv; //will call #1
return 0;
answered Nov 13 '18 at 6:40
Gaurav SehgalGaurav Sehgal
5,72611026
5,72611026
You beat me to it!
– Francis Cugler
Nov 13 '18 at 6:47
Thanks. This suggestion does work. For the deeper discussion, is it possible to make the two cases both work as no operands precedence need to be cared about for the user?
– Rubin
Nov 13 '18 at 6:57
Nice answer. However, this works only because you play with the order of the parameters (with an operator that is assumed to be commutative).
– Christophe
Nov 13 '18 at 7:06
@Rubin I think the term you are looking for is commutate and not precedence. The commutative property says thata*b
is equal tob*a
. Precedence is used to decide in which order several operators are executed:a + b * c
where multiplication has a higher precedence and will be calculated before the addition. Also here a link to a question about commutative property in the non-templated case: stackoverflow.com/questions/3764604/…
– Philipp
Nov 13 '18 at 7:41
@Philipp Thanks for the correction. The commutative property is indeed what I need.
– Rubin
Nov 13 '18 at 7:49
|
show 2 more comments
You beat me to it!
– Francis Cugler
Nov 13 '18 at 6:47
Thanks. This suggestion does work. For the deeper discussion, is it possible to make the two cases both work as no operands precedence need to be cared about for the user?
– Rubin
Nov 13 '18 at 6:57
Nice answer. However, this works only because you play with the order of the parameters (with an operator that is assumed to be commutative).
– Christophe
Nov 13 '18 at 7:06
@Rubin I think the term you are looking for is commutate and not precedence. The commutative property says thata*b
is equal tob*a
. Precedence is used to decide in which order several operators are executed:a + b * c
where multiplication has a higher precedence and will be calculated before the addition. Also here a link to a question about commutative property in the non-templated case: stackoverflow.com/questions/3764604/…
– Philipp
Nov 13 '18 at 7:41
@Philipp Thanks for the correction. The commutative property is indeed what I need.
– Rubin
Nov 13 '18 at 7:49
You beat me to it!
– Francis Cugler
Nov 13 '18 at 6:47
You beat me to it!
– Francis Cugler
Nov 13 '18 at 6:47
Thanks. This suggestion does work. For the deeper discussion, is it possible to make the two cases both work as no operands precedence need to be cared about for the user?
– Rubin
Nov 13 '18 at 6:57
Thanks. This suggestion does work. For the deeper discussion, is it possible to make the two cases both work as no operands precedence need to be cared about for the user?
– Rubin
Nov 13 '18 at 6:57
Nice answer. However, this works only because you play with the order of the parameters (with an operator that is assumed to be commutative).
– Christophe
Nov 13 '18 at 7:06
Nice answer. However, this works only because you play with the order of the parameters (with an operator that is assumed to be commutative).
– Christophe
Nov 13 '18 at 7:06
@Rubin I think the term you are looking for is commutate and not precedence. The commutative property says that
a*b
is equal to b*a
. Precedence is used to decide in which order several operators are executed: a + b * c
where multiplication has a higher precedence and will be calculated before the addition. Also here a link to a question about commutative property in the non-templated case: stackoverflow.com/questions/3764604/…– Philipp
Nov 13 '18 at 7:41
@Rubin I think the term you are looking for is commutate and not precedence. The commutative property says that
a*b
is equal to b*a
. Precedence is used to decide in which order several operators are executed: a + b * c
where multiplication has a higher precedence and will be calculated before the addition. Also here a link to a question about commutative property in the non-templated case: stackoverflow.com/questions/3764604/…– Philipp
Nov 13 '18 at 7:41
@Philipp Thanks for the correction. The commutative property is indeed what I need.
– Rubin
Nov 13 '18 at 7:49
@Philipp Thanks for the correction. The commutative property is indeed what I need.
– Rubin
Nov 13 '18 at 7:49
|
show 2 more comments
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53274692%2ftemplate-deduction-complaints-ambiguous-candidates%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown