鉴于以下计划:
#include <iostream>
#include <string>
using namespace std;
struct GenericType{
operator string(){
return "Hello World";
}
operator int(){
return 111;
}
operator double(){
return 123.4;
}
};
int main(){
int i = GenericType();
string s = GenericType();
double d = GenericType();
cout << i << s << d << endl;
i = GenericType();
s = GenericType(); //This is the troublesome line
d = GenericType();
cout << i << s << d << endl;
}
Run Code Online (Sandbox Code Playgroud)
它在Visual Studio 11上编译,但不是clang或gcc.这是有问题的,因为它要含蓄从转换GenericType到int …
c++ string conversion-operator overload-resolution implicit-conversion
这是一个简短的例子,用clang重现这个"没有可行的转换"柠檬,但对编译器行为的g ++差异有效.
#include <iostream>
struct A {
int i;
};
#ifndef UNSCREW_CLANG
using cast_type = const A;
#else
using cast_type = A;
#endif
struct B {
operator cast_type () const {
return A{i};
}
int i;
};
int main () {
A a{0};
B b{1};
#ifndef CLANG_WORKAROUND
a = b;
#else
a = b.operator cast_type ();
#endif
std::cout << a.i << std::endl;
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
住在Godbolt的
g ++(4.9,5.2)默默地编译; 而clang ++(3.5,3.7)编译它
如果 …
我不知道如何在一个简短的主题行中很好地表达这个问题,所以让我尝试一个更长的解释.假设我有这些异常类:
class ExceptionTypeA : public std::runtime_error
{
// stuff
};
class ExceptionTypeB : public std::runtime_error
{
// stuff
operator ExceptionTypeA() const; // conversion operator to ExceptionTypeA
};
Run Code Online (Sandbox Code Playgroud)
我可以这样做,并让它触发catch块吗?
try
{
throw ExceptionTypeB();
}
catch (ExceptionTypeA& a)
{
// will this be triggered?
}
Run Code Online (Sandbox Code Playgroud)
我猜它不会,这是不幸的,但我想我会问,因为我无法在网上或SO上找到任何信息.是的,我意识到我可以在我的编译器中运行程序,看看会发生什么,但这不会告诉我标准对这种行为的说法,只是我的编译器实现的(我不相信它).
给出以下转换运算符
struct A
{
template<typename T> explicit operator T&& () &&;
template<typename T> explicit operator T& () &;
template<typename T> explicit operator const T& () const&;
};
struct B {};
Run Code Online (Sandbox Code Playgroud)
我希望以下转换都是有效的,但有些会给出编译错误(实例):
A a;
A&& ar = std::move(a);
A& al = a;
const A& ac = a;
B&& bm(std::move(a)); // 1. OK
B&& bt(A{}); // 2. OK
B&& br(ar); // 3. error: no viable conversion from A to B
B& bl(al); // 4. OK
const B& bz(al); // 5. …Run Code Online (Sandbox Code Playgroud) c++ rvalue-reference conversion-operator c++11 ref-qualifier
下面的代码使用gcc 7.1.0编译,C++ 17设置,但不使用C++ 14 set(或Visual Studio 2017)编译.它很容易在Wandbox上重现.
要使它与C++ 11/14一起使用需要做些什么?
#include <iostream>
#include <chrono>
int main()
{
struct Convert
{
operator std::chrono::milliseconds()
{
std::cout << "operator std::chrono::milliseconds" << std::endl;
return std::chrono::milliseconds(10);
}
operator int64_t ()
{
std::cout << "operator int64_t" << std::endl;
return 5;
}
};
Convert convert;
std::chrono::milliseconds m(convert);
std::cout << m.count() << std::endl;
int64_t i(convert);
std::cout << i << std::endl;
}
Run Code Online (Sandbox Code Playgroud) 我有一些代码使用模板转换运算符来查找通过ADL找到的函数的返回类型.
简化的代码如下所示:
#include <type_traits>
template<typename S>
struct probe {
template<typename T, typename U = S, std::enable_if_t<
std::is_same<T&, U>::value &&
!std::is_const<T>::value, int> = 0>
operator T& ();
template<typename T, typename U = S&&, std::enable_if_t<
std::is_same<T&&, U>::value &&
!std::is_const<T>::value, int> = 0>
operator T&& ();
template<typename T, typename U = S, std::enable_if_t<
std::is_same<T const&, U>::value, int> = 0>
operator T const& () const;
template<typename T, typename U = S&&, std::enable_if_t<
std::is_same<T const&&, U>::value, int> = 0>
operator T const&& () const;
}; …Run Code Online (Sandbox Code Playgroud) 在从class B继承的类中A,可以使用using声明将in的成员(甚至是模板)带A进去B,如下所示:
struct A {
template <typename T>
void foo();
};
struct B : private A {
using A::foo;
};
Run Code Online (Sandbox Code Playgroud)
但是可以为转换模板完成吗?
struct A {
template <typename T>
operator T();
};
struct B : private A {
using A::operator /* ??? */;
};
Run Code Online (Sandbox Code Playgroud)
似乎没有办法通过名称来引用模板,但是我希望被证明是错误的或得到一些澄清。
c++ inheritance using-declaration conversion-operator language-lawyer
假设我们有程序void f(X2);。进一步假设我们有类型X1并且X2不共享继承层次结构。
我们想这样称呼它:f(X1{})并X1隐式转换为X2. 我们有两种选择来实现这一目标:
struct X2 {};
struct X1 { operator X2(); };
Run Code Online (Sandbox Code Playgroud)
struct X1 {};
struct X2 { X2(const X1&); };
Run Code Online (Sandbox Code Playgroud)
在实现方面,两者之间在定义顺序和访问私有数据的方式方面存在实际差异。
但从用户的角度来看,这两种方法是否会表现出不同的情况?如果是这样,两者中哪一个更可取?
即使我们对两者都进行标记,这个问题仍然是一样的explicit。然后出现的一个区别是,通过构造函数的转换仅在前一种情况下可用,但static_cast适用于任何一种情况。
c++ constructor conversion-operator implicit-conversion implicit-constructor
这是一个返回数组引用的转换函数:
struct S {
typedef int int_array_20[20];
operator int_array_20& ();
};
Run Code Online (Sandbox Code Playgroud)
没有可能做同样的事情typedef吗?我尝试过的:
struct S {
operator int (&()) [10];
};
Run Code Online (Sandbox Code Playgroud)
但克朗抱怨道:
error: C++ requires a type specifier for all declarations
operator int (&()) [10];
~ ^
error: conversion function cannot have any parameters
operator int (&()) [10];
^
error: must use a typedef to declare a conversion to 'int [10]'
error: conversion function cannot convert to an array type
Run Code Online (Sandbox Code Playgroud)
请问:
必须使用typedef来声明转换为'int [10]'
意味着typedef不可或缺?
编辑
如果typedef …
c++ typedef type-conversion conversion-operator language-lawyer
在下面的程序中 structS提供了两个转换运算符: indouble和 in long long int。然后一个类型的对象S被传递给一个函数f,重载为floatand double:
struct S {
operator double() { return 3; }
operator long long int() { return 4; }
};
void f( double ) {}
void f( float ) {}
int main() {
S s;
f( s );
}
Run Code Online (Sandbox Code Playgroud)
MSVC 编译器可以正常接受程序,并选择f( double )重载。f然而,GCC 和 Clang 都发现, demo的调用存在歧义:https: //gcc.godbolt.org/z/5csd5dfYz
看来MSVC在这里是对的,因为转换:
operator long long int()->f( float )不是提升。这是错的吗? …
c++ overloading conversion-operator language-lawyer overload-resolution
c++ ×9
c++11 ×2
c++-chrono ×1
c++14 ×1
c++17 ×1
clang ×1
clang++ ×1
constructor ×1
g++ ×1
inheritance ×1
overloading ×1
string ×1
templates ×1
typedef ×1