gpt4 book ai didi

c++ - 子类坚持调用模板而不是构造函数

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:45:21 25 4
gpt4 key购买 nike

以下不使用 g++ 4.4.7 编译,在命令行上传递 --std==c++0x:

#include <algorithm>
#include <iostream>

template <typename T>
class A
{
public:
T v;

A() { std::cout << "A default constructor\n"; }
A(const A& i): v(i.v) { std::cout << "A copy constructor\n"; }
A(A&& i): v(std::move(i.v)) { std::cout << "A move constructor\n"; }
#if 1 // turn this off to fix the version without static_cast
template <typename V>
explicit A(const V& i): v(i) {}
#endif
};

class B: public A<int>
{
public:
B() { std::cout << "B default constructor\n"; }
#if 1 // turn this off to get static_cast that makes it compile
B(const B& i): A<int>(i) {
std::cout << "B copy constructor\n"; }
B(B&& i): A<int>(std::move(i)) {
std::cout << "B move constructor\n"; }
#else
B(const B& i): A<int>(static_cast<const A<int> &>(i)) {
std::cout << "B copy constructor\n"; }
B(B&& i): A<int>(std::move(static_cast<A<int> &&>(i))) {
std::cout << "B move constructor\n"; }
#endif
};

B foo() {
B t;
return t;
}

int main() {
B t(foo());
B t2(std::move(t));
std::cout << "Result is " << t2.v << std::endl;
return 0;
}

产生以下错误,复制和移动构造函数似乎调用显式 A 模板而不是 A 的明显复制/移动构造函数:

container.cpp: In constructor ‘A<T>::A(const V&) [with V = B, T = int]’:
container.cpp:26: instantiated from here
container.cpp:17: error: cannot convert ‘const B’ to ‘int’ in initialization

关闭第一个 #if 1 会删除模板,这会编译并生成预期的调用。关闭第二个 #if 1 也可以让它工作(但是在我们的代码中做同样的事情会很痛苦并且需要大量的仔细编辑)。

目前我通过将模板构造函数更改为此并将 bool 添加到所有用户来解决这个问题,但这很丑陋:

A(const V&i, bool dummy): v(i) {}

问题:

  1. 这是 GCC 中的错误吗?
  2. 如果不是,有人可以解释为什么会这样吗?
  3. 建议的修复方法是什么?我的 static_casts 正确吗?

最佳答案

where it seems the copy and move constructors call the explicit A template rather than the obvious copy/move constructors of A:

调用 A(A const&) 构造函数没有什么明显的地方:你正在调用 A 构造函数,参数类型为 B const&,最好的匹配就是模板(完全匹配)而不是 A(A const&)不是> 完全匹配(它需要隐式向上转换)。

所以这个行为完全符合预期。如果您不希望这样做,请更改模板,以便在使用 A 的子类调用时将其禁用(通过 SFINAE):

template <typename V>
explicit A(const V& i,
typename std::enable_if<! std::is_base_of<A, V>::value>::type* = nullptr)
: v(i) {}

(未经测试!)

关于c++ - 子类坚持调用模板而不是构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20458134/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com