使用带 Visual Studio 10 的类型转换运算符重载时出现 C2440 错误
C2440 error when using typecasting operator overload with Visual Studio 10
我遇到了 C2440 错误:
C:\code>cl test.cpp /EHsc
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
test.cpp
test.cpp(18) : error C2440: 'initializing' : cannot convert from 'D<TYPE,SELECTOR>' to 'int'
with
[
TYPE=int,
SELECTOR=int
]
Ambiguous user-defined-conversion
当我尝试用 visual studio 10 编译以下测试代码时,它似乎在 clang -Weverything
和 armcc 上运行良好。
这不起作用是否有特殊原因,除了 "don't do that" 之外还有其他解决方法吗?
#include <iostream>
template <typename TYPE, typename SELECTOR = int> struct D {
TYPE x;
D() : x(2) {}
D(TYPE X) : x(X) {}
operator const TYPE&() const { return x; }
};
template <typename TYPE> struct D<TYPE, int> : public D<TYPE, char> {
D() : D<TYPE, char>(3) {}
operator TYPE&() { return D<TYPE, char>::x; }
};
int main() {
D<int, int> test3;
int t3 = test3;
D<int, char> test2;
int t2 = test2;
std::cout << +t3 << " " << +t2 << "\n"; // Expected output "3 2" (which we get from clang)
return 0;
}
编辑:我知道 D<TYPE, int>
案例提供左值,而 D<TYPE, non-int>
案例仅提供右值。那是故意的。
operator TYPE&()
有两个功能:
public D<int, int>::operator int&()
private D<int, char>::operator const int&() const
可以显式调用它:
int t3 = test3.::D<int, int>::operator int&();
关于 gcc 是否允许调用(如果是公共继承):
int t3 = test3.::D<int, char>::operator const int&();
但 msvc 不是
gcc 允许两种变体,似乎是正确的:
D<int, int> test3;
const D<int, int> test4;
int t3 = test3; // called D<int, int>::operator int&();
int t4 = test4; // called D<int, char>::operator const int&() const;
msvc 只允许第二种变体。
msvc不认为test3不是const,不selectconst和非const函数
似乎是 msvc 错误。
Ambiguous user-defined-conversion
模棱两可是关键词。
D<int, int> test3;
int t3 = test3;
这里编译器不知道是使用const int &D<int, char>::operator const int &()
还是int &D<int, int>::operator int &()
。
问题是 t3
是 int
而不是 int&
或 const int&
。
如果你真的使用引用,一切正常(或至少如预期的那样):
D<int, int> test3;
int& t31 = test3; //OK
const int& t32 = test3; //OK
D<int, char> test2;
int& t21 = test2; //Doesn't work
const int& t22 = test2; //OK
问题是编译器决定是使用基础 class 的 const 版本还是继承 class.
的非 const 版本
我建议您在继承 class 中重载运算符的 const 版本,以便编译器可以仅从这个 class 中选择使用哪个:
#include <iostream>
template <typename TYPE, typename SELECTOR = int> struct D {
TYPE x;
D() : x(2) {}
D(TYPE X) : x(X) {}
operator const TYPE&() const { return x; }
};
template <typename TYPE> struct D<TYPE, int> : public D<TYPE, char> {
D() : D<TYPE, char>(3) {}
operator const TYPE&() const { return D<TYPE, char>::x; }
operator TYPE&() { return D<TYPE, char>::x; }
};
int main() {
D<int, int> test3;
int t3 = test3; //OK
int& t31 = test3; //OK
const int& t32 = test3; //OK
D<int, char> test2;
int t2 = test2; //OK
//int& t21 = test2; //Doesn't work
const int& t22 = test2; //OK
std::cout << +t3 << " " << +t2 << "\n"; // Expected output "3 2" (which we get from clang)
return 0;
}
解决这个问题的其他方法:
您现在可以手动转换为 int&
D<int, int> test3;
int t3 = (int&)test3;
或手动转换为 const int&
D<int, int> test3;
int t3 = (const int&)test3;
或显式调用函数
D<int, int> test3;
int t3 = test3.operator int &();
或
D<int, int> test3;
int t3 = test3.operator const int &();
或者你可以让两者都发挥作用 const
template <typename TYPE> struct D<TYPE, int> : public D<TYPE, char> {
D() : D<TYPE, char>(3) {}
operator const TYPE&() const { return D<TYPE, char>::x; }
};
或者您可以删除函数的重新定义(因为 TYPE 不会改变)。
template <typename TYPE, typename SELECTOR = int> struct D {
TYPE x;
D() : x(2) {}
D(TYPE X) : x(X) {}
operator const TYPE&() const { return x; }
};
template <typename TYPE> struct D<TYPE, int> : public D<TYPE, char> {
D() : D<TYPE, char>(3) {}
};
但我猜后两种变体不是您想要的,因为 const
.
我遇到了 C2440 错误:
C:\code>cl test.cpp /EHsc
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
test.cpp
test.cpp(18) : error C2440: 'initializing' : cannot convert from 'D<TYPE,SELECTOR>' to 'int'
with
[
TYPE=int,
SELECTOR=int
]
Ambiguous user-defined-conversion
当我尝试用 visual studio 10 编译以下测试代码时,它似乎在 clang -Weverything
和 armcc 上运行良好。
这不起作用是否有特殊原因,除了 "don't do that" 之外还有其他解决方法吗?
#include <iostream>
template <typename TYPE, typename SELECTOR = int> struct D {
TYPE x;
D() : x(2) {}
D(TYPE X) : x(X) {}
operator const TYPE&() const { return x; }
};
template <typename TYPE> struct D<TYPE, int> : public D<TYPE, char> {
D() : D<TYPE, char>(3) {}
operator TYPE&() { return D<TYPE, char>::x; }
};
int main() {
D<int, int> test3;
int t3 = test3;
D<int, char> test2;
int t2 = test2;
std::cout << +t3 << " " << +t2 << "\n"; // Expected output "3 2" (which we get from clang)
return 0;
}
编辑:我知道 D<TYPE, int>
案例提供左值,而 D<TYPE, non-int>
案例仅提供右值。那是故意的。
operator TYPE&()
有两个功能:
public D<int, int>::operator int&()
private D<int, char>::operator const int&() const
可以显式调用它:
int t3 = test3.::D<int, int>::operator int&();
关于 gcc 是否允许调用(如果是公共继承):
int t3 = test3.::D<int, char>::operator const int&();
但 msvc 不是
gcc 允许两种变体,似乎是正确的:
D<int, int> test3;
const D<int, int> test4;
int t3 = test3; // called D<int, int>::operator int&();
int t4 = test4; // called D<int, char>::operator const int&() const;
msvc 只允许第二种变体。
msvc不认为test3不是const,不selectconst和非const函数
似乎是 msvc 错误。
Ambiguous user-defined-conversion
模棱两可是关键词。
D<int, int> test3;
int t3 = test3;
这里编译器不知道是使用const int &D<int, char>::operator const int &()
还是int &D<int, int>::operator int &()
。
问题是 t3
是 int
而不是 int&
或 const int&
。
如果你真的使用引用,一切正常(或至少如预期的那样):
D<int, int> test3;
int& t31 = test3; //OK
const int& t32 = test3; //OK
D<int, char> test2;
int& t21 = test2; //Doesn't work
const int& t22 = test2; //OK
问题是编译器决定是使用基础 class 的 const 版本还是继承 class.
的非 const 版本我建议您在继承 class 中重载运算符的 const 版本,以便编译器可以仅从这个 class 中选择使用哪个:
#include <iostream>
template <typename TYPE, typename SELECTOR = int> struct D {
TYPE x;
D() : x(2) {}
D(TYPE X) : x(X) {}
operator const TYPE&() const { return x; }
};
template <typename TYPE> struct D<TYPE, int> : public D<TYPE, char> {
D() : D<TYPE, char>(3) {}
operator const TYPE&() const { return D<TYPE, char>::x; }
operator TYPE&() { return D<TYPE, char>::x; }
};
int main() {
D<int, int> test3;
int t3 = test3; //OK
int& t31 = test3; //OK
const int& t32 = test3; //OK
D<int, char> test2;
int t2 = test2; //OK
//int& t21 = test2; //Doesn't work
const int& t22 = test2; //OK
std::cout << +t3 << " " << +t2 << "\n"; // Expected output "3 2" (which we get from clang)
return 0;
}
解决这个问题的其他方法:
您现在可以手动转换为 int&
D<int, int> test3;
int t3 = (int&)test3;
或手动转换为 const int&
D<int, int> test3;
int t3 = (const int&)test3;
或显式调用函数
D<int, int> test3;
int t3 = test3.operator int &();
或
D<int, int> test3;
int t3 = test3.operator const int &();
或者你可以让两者都发挥作用 const
template <typename TYPE> struct D<TYPE, int> : public D<TYPE, char> {
D() : D<TYPE, char>(3) {}
operator const TYPE&() const { return D<TYPE, char>::x; }
};
或者您可以删除函数的重新定义(因为 TYPE 不会改变)。
template <typename TYPE, typename SELECTOR = int> struct D {
TYPE x;
D() : x(2) {}
D(TYPE X) : x(X) {}
operator const TYPE&() const { return x; }
};
template <typename TYPE> struct D<TYPE, int> : public D<TYPE, char> {
D() : D<TYPE, char>(3) {}
};
但我猜后两种变体不是您想要的,因为 const
.