gpt4 book ai didi

c++ - 传递初始化列表时可变参数模板参数推导失败

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:11:30 28 4
gpt4 key购买 nike

Bar 包含 std::arraystd::pairstd::vector FooValueAdaptor 的。FooValueAdaptorint 隐式转换为 boolFooValue,这在这个人为的示例中没有什么意义,但在我的应用程序。我实现了一个方便的函数 Bar::addEntries 用于一次添加多个条目,但是使用两个以上的参数调用它无法使用 GCC 4.8.0 进行编译。请参阅下面的错误消息。

#include <array>
#include <utility>
#include <vector>

enum class FooValue {
A,
B,
C
};

class FooValueAdaptor {
public:
FooValueAdaptor(bool value)
: m_value(static_cast<FooValue>(value)) {
}

FooValueAdaptor(int value)
: m_value(static_cast<FooValue>(static_cast<bool>(value))) {
}

FooValueAdaptor(FooValue value)
: m_value(value) {
}

operator FooValue() {
return m_value;
}

operator bool() {
return m_value == FooValue::C;
}

private:
FooValue m_value;
};

template<std::size_t nFirst, std::size_t nSecond>
class Bar {
public:
typedef std::array<FooValueAdaptor, nFirst> First;
typedef std::array<FooValueAdaptor, nSecond> Second;
typedef std::pair<First, Second> Entry;

Bar()
: m_table() {
}

void addEntry(First first, Second second) {
m_table.push_back(std::make_pair(first, second));
}

template <typename... Args>
void addEntries() {
}

template <typename... Args>
void addEntries(First first, Second second, Args... args) {
addEntry(first, second);
addEntries(args...);
}

private:
std::vector<Entry> m_table;
};

int main(int argc, char **argv) {
Bar<2, 1> b;

b.addEntry({ 0, 0 }, { 0 });
b.addEntries(
{ 0, 1 }, { 0 },
{ 1, 0 }, { 0 },
{ 1, 1 }, { 1 }
);

return 0;
}

编译器错误信息:

test.cpp: In function ‘int main(int, char**)’:
test.cpp:74:2: error: no matching function for call to ‘Bar<2ul, 1ul>::addEntries(<brace-enclosed initializer list>, <brace-enclosed initializer list>, <brace-enclosed initializer list>, <brace-enclosed initializer list>, <brace-enclosed initializer list>, <brace-enclosed initializer list>)’
);
^
test.cpp:74:2: note: candidates are:
test.cpp:53:7: note: template<class ... Args> void Bar<nFirst, nSecond>::addEntries() [with Args = {Args ...}; long unsigned int nFirst = 2ul; long unsigned int nSecond = 1ul]
void addEntries() {
^
test.cpp:53:7: note: template argument deduction/substitution failed:
test.cpp:74:2: note: candidate expects 0 arguments, 6 provided
);
^
test.cpp:57:7: note: void Bar<nFirst, nSecond>::addEntries(Bar<nFirst, nSecond>::First, Bar<nFirst, nSecond>::Second, Args ...) [with Args = {}; long unsigned int nFirst = 2ul; long unsigned int nSecond = 1ul; Bar<nFirst, nSecond>::First = std::array<FooValueAdaptor, 2ul>; Bar<nFirst, nSecond>::Second = std::array<FooValueAdaptor, 1ul>]
void addEntries(First first, Second second, Args... args) {
^
test.cpp:57:7: note: candidate expects 2 arguments, 6 provided

我怎样才能帮助编译器进行推导?

最佳答案

你需要明确地告诉编译器你需要什么:

void addEntries(std::initializer_list<std::pair<First, Second>> il) {
for( const auto& e : il ) {
addEntry(e.first,e.second);
}
}

并这样调用它:

b.addEntry({{ 0, 0 }}, {{ 0 }});
b.addEntries({
{{{ 0, 1 }}, {{ 0 }}},
{{{ 1, 0 }}, {{ 0 }}},
{{{ 1, 1 }}, {{ 1 }}}
});

请注意大量的大括号,但我认为以上实际上是唯一正确的语法。 GCC 4.8 和 Clang 3.2 都接受更少的括号,但 Clang 给出了很多警告,上面修复了这个问题。有些人已经working on a "fix" ,但这需要一些时间。

关于c++ - 传递初始化列表时可变参数模板参数推导失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15745677/

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