相关疑难解决方法(0)

松耦合隐式转换

类型在语义上等效时,隐式转换非常有用.例如,假设两个库以相同的方式实现类型,但在不同的命名空间中.或者只是一种大多数相同的类型,除了一些语义糖在这里和那里.现在,您无法将一种类型传递给设计为使用另一种的函数(在其中一个库中),除非该函数是模板.如果不是,你必须以某种方式将一种类型转换为另一种类型.这应该是微不足道的(或者其他类型在后面都不是那么相同!)但是调用转换显然会使代码膨胀,而且函数调用几乎毫无意义.虽然这样的转换函数实际上可能会复制一些值,但它们从高级"程序员"的角度来看基本上什么都不做.

隐式转换构造函数和运算符显然可以提供帮助,但它们引入了耦合,因此其中一种类型必须知道另一种类型.通常,至少在处理库时,情况并非如此,因为其中一种类型的存在使另一种类型变得冗余.此外,您不能总是更改库.

现在我看到有关如何在用户代码中进行隐式转换的两个选项:

  1. 第一个是提供代理类型,它为所有涉及的类型实现转换操作符和转换构造函数(和赋值),并始终使用它.

  2. 第二个需要对库进行最小的更改,但允许很大的灵活性:为每个可以在外部选择启用的相关类型添加转换构造函数.

例如,对于类型A添加构造函数:

template <class T> A(
  const T& src,
  typename boost::enable_if<conversion_enabled<T,A>>::type* ignore=0
)
{
  *this = convert(src);
}
Run Code Online (Sandbox Code Playgroud)

和一个模板

template <class X, class Y>
struct conversion_enabled : public boost::mpl::false_ {};
Run Code Online (Sandbox Code Playgroud)

默认情况下禁用隐式转换.

然后要启用两种类型之间的转换,请专门化模板:

template <> struct conversion_enabled<OtherA, A> : public boost::mpl::true_ {};
Run Code Online (Sandbox Code Playgroud)

并实现一个convert可以通过ADL找到的函数.

我个人更喜欢使用第二种变体,除非有强烈的反对意见.

现在回答实际问题:关联隐式转换类型的首选方法是什么?我的建议是好主意吗?两种方法都有任何缺点吗?允许这样的转换是危险的吗?如果库类实现者通常会提供第二种方法,那么它们的类型很可能会被软件复制,而这些软件很可能与它们一起使用(我在考虑使用3d渲染中间件,其中大多数软件包实现了3D向量).

c++ boost-mpl enable-if

25
推荐指数
1
解决办法
1061
查看次数

在C++中可以使用哪些其他有用的强制转换

C++附带了四个内置的强制转换.

  1. static_cast
  2. dynamic_cast
  3. const_cast
  4. reinterpret_cast

不要说皱眉头C (style*)cast.

另外,boost提供了一个lexical_cast,你还有其他有用的演员阵容吗?

c++ casting

14
推荐指数
3
解决办法
2089
查看次数

为什么我不能在传递给参数时隐式地构造给定合适构造函数的对象?

在下面的例子中,为什么我不能简单地传递stringprintFoo()

#include <string>
#include <iostream>

using namespace std;

class Foo {
public:
  Foo(const Foo &foo) : str(foo.str) {}
  Foo(string str) : str(str) {}

  string str;
};

void printFoo(Foo foo) {
  cout << foo.str << endl;
}

int main() {
  Foo foo("qux");
  printFoo(foo); // OK

  printFoo("qix"); // error: no matching function for call to 'printFoo'

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

无论出于何种原因,我都在脑海中自动确定并使用构造函数来构造对象.

为什么我不能这样做,但是我可以将char[n]常数传递给接受a的参数std::string,例如?

c++

12
推荐指数
3
解决办法
809
查看次数

C++模板和隐式类型转换

我有以下代码:

#include <iostream>
#include "boost/shared_ptr.hpp"

using boost::shared_ptr;

class Base {
 public:
  virtual ~Base() {}
  virtual void print() = 0;
};

template <typename T>
class Child : public Base {
 public:
  virtual void print() {
    std::cout << "in Child" << std::endl;
  }
};

class GrandChild : public Child<int> {
 public:
  virtual void print() {
    std::cout << "in GrandChild" << std::endl;
  }
};

template <typename T>
void call_print(shared_ptr<Child<T> > a) {
  a->print();
}

void call_base_print(shared_ptr<Base> a) {
  a->print();
}

int main() { …
Run Code Online (Sandbox Code Playgroud)

c++

4
推荐指数
1
解决办法
1394
查看次数

c ++ cast overload等价物

我想知道在c ++中是否有可能像在这个C#示例中那样实现相同的转换重载:

class A {
    public static implicit operator A(string s) {
        return new A();
    }
    public static implicit operator A(double d) {
        return new A();
    }        
    static void Main(string[] args) {
        A a = "hello";
        A b = 5.0;
    }
}
Run Code Online (Sandbox Code Playgroud)

在C++中它应该是这样的:

#include <string>
using namespace std;

class A{
    /*SOME CAST OVERLOADING GOES HERE*/
};


void main(){
    A a = "hello";
    A b = 5.0;
}
Run Code Online (Sandbox Code Playgroud)

你能帮助我如何使这个演员超载吗?

c# c++ casting

3
推荐指数
1
解决办法
735
查看次数

转换和向上转换

我想完全理解转换,即确保我知道函数调用何时会导致隐式转换,何时会导致编译错误.我已经知道,当且仅当有一种单一的方法将变量转换为以下列表中的两个步骤(按优先级排序)时,才能进行转换:

1. Exact match
2. Promotion
3. Conversion
4. User defined conversion
Run Code Online (Sandbox Code Playgroud)

其中,顺便我的理解是(你可以指正),是推广是原语转化成更大的原始类型,如短整型,浮点翻番,等等; 转换是基元之间的任何转换,不是促销,例如int到char等; 用户定义的转换是使用转换构造函数和转换运算符的类转换.现在,我也知道继承意味着和Is-A关系,这意味着派生类是基类,因此将派生类发送到期望引用基类的函数应该有效.结合上面的两个概念,我们应该得到以下我写的例子,应该工作:

class C {};
class D: public C
{
public:
D(int x){}
};
void f(C& c) {}
f(3);
Run Code Online (Sandbox Code Playgroud)

因为D可以从int转换为,而D是C.但是这个代码没有被编译.这是为什么?如何解决矛盾?你能否解释一下这个问题?谢谢!

c++ reference upcasting implicit-conversion

3
推荐指数
1
解决办法
619
查看次数

char []如何在参数中解释为const std :: strings

我最近意识到我可以这样做:

void someFunc(const std::string &str)
{
   //content
}

...
someFunc("Hello World"); //this works
Run Code Online (Sandbox Code Playgroud)

我想知道它是如何工作的以及为什么它有效.

谢谢

c++ string

2
推荐指数
1
解决办法
815
查看次数