花了1或2个小时来隔离由元编程混乱所包围的编译错误,生成可怕的编译消息,这是一个简单的例子来说明我的问题:
#include <iostream>
#include <type_traits>
#include <array>
#include <utility>
#include <tuple>
template <class Crtp, class... Types>
struct Base
{
Base(const Types&... rhs) :
data(std::forward_as_tuple(rhs...)) {;}
std::tuple<Types...> data;
};
struct Derived
: public Base<Derived, std::array<double, 3>>
{
template <class... Args>
Derived(Args&&... args) :
Base<Derived, std::array<double, 3>>(std::forward<Args>(args)...) {;}
};
int main(int argc, char* argv[])
{
Derived a(std::array<double, 3>({{1, 2, 3}}));
Derived b(a);
Derived c(std::array<double, 3>());
Derived d(c); // Not working : why ?
return 0;
}
这是用g ++ 4.8.1编译的,当我尝试复制c
中的d
而不是a
中的b
时,我不明白为什么编译器会抱怨
这是错误:
main.cpp: In instantiation of ‘Derived::Derived(Args&& ...) [with Args = {Derived (&)(std::array<double, 3ul> (*)())}]’:
main.cpp:28:16: required from here
main.cpp:20:73: error: no matching function for call to ‘Base<Derived, std::array<double, 3ul> >::Base(Derived (&)(std::array<double, 3ul> (*)()))’
Base<Derived, std::array<double, 3>>(std::forward<Args>(args)...) {;}
^
main.cpp:20:73: note: candidates are:
main.cpp:10:5: note: Base<Crtp, Types>::Base(const Types& ...) [with Crtp = Derived; Types = {std::array<double, 3ul>}]
Base(const Types&... rhs) :
^
main.cpp:10:5: note: no known conversion for argument 1 from ‘Derived(std::array<double, 3ul> (*)())’ to ‘const std::array<double, 3ul>&’
main.cpp:8:8: note: constexpr Base<Derived, std::array<double, 3ul> >::Base(const Base<Derived, std::array<double, 3ul> >&)
struct Base
^
main.cpp:8:8: note: no known conversion for argument 1 from ‘Derived(std::array<double, 3ul> (*)())’ to ‘const Base<Derived, std::array<double, 3ul> >&’
main.cpp:8:8: note: constexpr Base<Derived, std::array<double, 3ul> >::Base(Base<Derived, std::array<double, 3ul> >&&)
main.cpp:8:8: note: no known conversion for argument 1 from ‘Derived(std::array<double, 3ul> (*)())’ to ‘Base<Derived, std::array<double, 3ul> >&&’
答案 0 :(得分:3)
Derived c(std::array<double, 3>());
是一个函数c
的声明,它返回一个Derived
并接受一个未命名的类型为的参数指向函数,该函数不带参数并返回std::array<double, 3>
。
因此Derived d(c)
尝试从函数Derived
调用c
构造函数。这就是海湾合作委员会在这里所说的:
main.cpp: In instantiation of ‘Derived::Derived(Args&& ...) [with Args = {Derived (&)(std::array<double, 3ul> (*)())}]’:
试试这个:
Derived c{std::array<double, 3>{}};
答案 1 :(得分:3)
适用于:
Derived c(std::array<double, 3> {});
编译器会考虑
中的参数Derived c(std::array<double, 3>());
是一个功能。
clang对此发出警告:
!!warning: parentheses were disambiguated as a function declarator.
答案 2 :(得分:0)
首先使Derived构造函数显式化。 如果这没有帮助添加复制构造函数,但我不认为这是必需的