相关疑难解决方法(0)

为什么auto x {3}推导出initializer_list?

我喜欢autoC++ 11.太棒了.但它有一个不一致,真的让我紧张,因为我一直绊倒它:

int i = 3;       // i is an int with value 3
int i = int{3};  // i is an int with value 3
int i(3);        // i is an int with value 3 (possibly narrowing, not in this case)
int i{3};        // i is an int with value 3

auto i = 3;      // i is an int with value 3
auto i = int{3}; // i is an int with value 3
auto i(3); …
Run Code Online (Sandbox Code Playgroud)

c++ initializer-list auto c++11 type-deduction

56
推荐指数
1
解决办法
4532
查看次数

使用rvalue initializer_list进行类型推断

在以下代码中

#include <initializer_list>
#include <utility>

template<typename T> void f(T&& x) {}
template<typename T> void g(std::initializer_list<T> x) {}

int main()
{
    auto   x = {0}; // OK
    auto&& y = {0}; // OK
    g(x); // OK
    g(std::move(x)); // OK
    g({0}); // OK
    f(x); // OK
    f(std::move(x)); // OK
    f({0}); // failure
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

rvalue initializer_list可以推导,auto但不能推断template.

为什么C++会禁止这个?

c++ c++11

11
推荐指数
1
解决办法
371
查看次数

转发初始化列表表达式

初始化列表表达式非常便于初始化C++容器:

std::vector<int>({1, 2, 3})
Run Code Online (Sandbox Code Playgroud)

......但似乎一个括号内的初始化列表表达式,如{1,2,3}绑定到需要的功能std::initializer_list<int>-它并不似乎绑定到一个通用(转发)参考:

template <class T>
void foo(T&& v)
{
  std::vector<int>(std::forward<T>(v));
}

int main()
{
  foo({1, 2, 3})
}
Run Code Online (Sandbox Code Playgroud)

这输出:

test2.cpp:11:6: note: template<class U> void foo(U&&)
test2.cpp:11:6: note:   template argument deduction/substitution failed:
test2.cpp:33:13: note:   couldn't deduce template parameter ‘U’
Run Code Online (Sandbox Code Playgroud)

(这是GCC 4.7.2的结果.)

遗憾的是,这意味着我们无法转发初始化列表表达式.既然这样做很方便,我想问为什么这不起作用?为什么括号封闭的初始化列表表达式不能绑定到转发引用?或者这是允许的,也许我的编译器太老了?

c++ templates initializer-list c++11

11
推荐指数
2
解决办法
3456
查看次数

关于std :: variant提出的接口中三个构造函数的问题

为什么构造函数(4)std::variant来自http://en.cppreference.com/w/cpp/utility/variant/variant?似乎它会在代码中引起很多歧义,否则可以通过显式来避免.例如,cppreference上的代码示例突出显示用户可能不会注意到的可能的歧义(第三行)

variant<string> v("abc"); // OK
variant<string, string> w("abc"); // ill-formed, can't select the alternative to convert to
variant<string, bool> w("abc"); // OK, but chooses bool
Run Code Online (Sandbox Code Playgroud)

有些情况下绝对需要吗?

另一个问题是为什么需要从同一个cppreference页面构造函数(6)和(8).(5)和(7)不符合(6)和(8)的目的吗?我可能误解了他们的用法..


对于读者来说,我在问题中提到的构造函数是

constexpr variant();              // (1)    (since C++17)

variant(const variant& other);    // (2)    (since C++17)

variant(variant&& other);         // (3)    (since C++17)

template< class T >               // (4)    (since C++17)
constexpr variant(T&& t);

template< class T, class... Args >
constexpr explicit variant(std::in_place_type_t<T>, Args&&... args); // (5) (since C++17)

template< class T, …
Run Code Online (Sandbox Code Playgroud)

c++ variant c++17

11
推荐指数
1
解决办法
808
查看次数

std :: initializer_list <int>({1,2,3})和{1,2,3}之间有什么区别?

我有以下模板功能:

template<typename T> void foo2(T t) {}
Run Code Online (Sandbox Code Playgroud)

我知道我不能用它来调用它:

foo2({1,2,3});
Run Code Online (Sandbox Code Playgroud)

因为初始化列表是模板参数的非推导上下文.我必须使用:

foo2<std::initializer_list<int>>({1,2,3});
Run Code Online (Sandbox Code Playgroud)

但我也可以用:

foo2(std::initializer_list<int>({1,2,3}));
Run Code Online (Sandbox Code Playgroud)

这让我想知道有什么区别:{1,2,3}std::initializer_list<int>({1,2,3})

c++ c++11

5
推荐指数
1
解决办法
199
查看次数