我创建了一个模板如下
template<typename T>
void f(T const& t) { }
Run Code Online (Sandbox Code Playgroud)
我希望这可以通过容器调用,也可以通过初始化列表调用.我认为这将是initializer_list<int>,如下调用.
f({1, 2, 3});
Run Code Online (Sandbox Code Playgroud)
但GCC表现得好像不符合标准
m.cpp: In function 'int main()':
m.cpp:6:25: warning: deducing 'const T' as 'const std::initializer_list<int>'
m.cpp:4:6: warning: in call to 'void f(const T&) [with T = std::initializer_list<int>]'
m.cpp:6:25: warning: (you can disable this with -fno-deduce-init-list)
Run Code Online (Sandbox Code Playgroud)
谁能解释我如何在没有警告的情况下完成这项工作?谢谢!
在开发应用程序时,我遇到了以下问题.我想std::list<string>在给定的函数指针为null时返回空,否则返回该函数的结果.这是我的代码的简化版本:
typedef std::list<std::string> (*ParamGenerator)();
std::list<std::string> foo() {
/* ... */
ParamGenerator generator = ...;
if(generator)
return generator();
else
return {};
}
Run Code Online (Sandbox Code Playgroud)
但是,我通常喜欢?:在这些情况下使用ternary()运算符,所以我尝试这样使用它(像往常一样):
return generator ? generator() : {};
Run Code Online (Sandbox Code Playgroud)
但得到了这个错误:
somefile.cpp:143:46: error: expected primary-expression before ‘{’ token
somefile.cpp:143:46: error: expected ‘;’ before ‘{’ token
Run Code Online (Sandbox Code Playgroud)
这是否意味着我不能使用三元运算符来返回使用其构造函数创建的对象initializer_list?这有什么特别的原因吗?
为什么这段代码无效?
auto foo=[](){
return {1,2};
};
Run Code Online (Sandbox Code Playgroud)
但是,这是有效的,因为initializer list它仅用于初始化vectornot以返回自身:
auto foo=[]()->std::vector<int>{
return {1,2};
};
Run Code Online (Sandbox Code Playgroud)
为什么我不能回来initializer list?它可能很有用.例如,一个lambda可用于初始化a vector或a list或...具有某些默认值.
下面的代码段在 vc++ 和 clang++ 中编译得很好,但在 gcc (inc 9.2) 上失败,除非我添加一个显式的强制转换。哪个编译器就在这里?
#include <initializer_list>
template<typename T>
void Task(void) {}
int main()
{
for(auto p_task: {&Task<int>}) {} // error
// for(auto p_task: {static_cast<void (*)(void)>(&Task<int>)}) {} // ok
}
Run Code Online (Sandbox Code Playgroud)
#include <initializer_list>
template<typename T>
void Task(void) {}
int main()
{
for(auto p_task: {&Task<int>}) {} // error
// for(auto p_task: {static_cast<void (*)(void)>(&Task<int>)}) {} // ok
}
Run Code Online (Sandbox Code Playgroud)
c++ templates initializer-list template-argument-deduction c++17
过去几天我一直在玩C++ 11,我想出了一些奇怪的东西.
如果我想统一初始化一个int:
int a{5};
Run Code Online (Sandbox Code Playgroud)
但是如果我对std :: vector做同样的事情:
std::vector<int> b{2};
Run Code Online (Sandbox Code Playgroud)
不构造一个两元素数组,而是一个具有一个值为2的元素的数组.似乎要获得这种效果,需要更加明确它:
std::vector<int> c{{2}};
std::vector<int> d = {2};
Run Code Online (Sandbox Code Playgroud)
但不像b的声明 - 这似乎不一致.我已经看到了其他一些相同的效果.我要问的是 - 这是最终C++ 11标准中的这种行为,还是只是在早期实施的草案中?如果是这样,为什么标准委员会会包含这种行为?看起来它破坏了统一初始化的整个目的,因为必须记住哪些类具有初始化列表构造函数,并且只使用old()语法而不是{}.或者一个人放弃统一初始化.
这似乎是一个很大的"陷阱".但是我不知道它可能有优点.
编辑:此代码:
#include <iostream>
#include <vector>
int main() {
std::vector<int> a{2};
for (auto x: a) {
std::cout << x << std::endl;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在gcc 4.6.2上输出"2"
我的情况可以归纳如下:
class Test
{
Test();
int MySet[10];
};
Run Code Online (Sandbox Code Playgroud)
是否可以MySet在初始化列表中初始化?
像这种初始化列表:
Test::Test() : MySet({1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {}
Run Code Online (Sandbox Code Playgroud)
有没有办法在类的初始化列表中初始化一个常量大小的成员数组?
我发现 Clang-12、Clang-13 和 Clang-14 具有以下标准行为c++17:
enum class FOO {
VALUE
};
enum class BAR {
VALUE
};
FOO value1{BAR::VALUE}; // OK
FOO value2 = BAR::VALUE; // Error
Run Code Online (Sandbox Code Playgroud)
为什么会有差异?我期望enum class100% 类型安全。
可以将push_back不可复制但可移动类型的rvalues转换为该类型的向量:
#include <vector>
struct S
{
S(int);
S(S&&);
};
int main()
{
std::vector<S> v;
v.push_back(S(1));
v.push_back(S(2));
v.push_back(S(3));
}
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试初始化列表构造具有相同rvalues的向量时,我得到关于所需的复制构造函数的错误:
#include <vector>
struct S
{
S(int);
S(S&&);
};
int main()
{
std::vector<S> v = {S(1), S(2), S(3)};
}
Run Code Online (Sandbox Code Playgroud)
我在GCC 4.7中遇到以下错误:
In file included from include/c++/4.7.0/vector:63:0,
from test.cpp:1:
include/c++/4.7.0/bits/stl_construct.h: In instantiation of 'void std::_Construct(_T1*, _Args&& ...) [with _T1 = S, _Args = {const S&}]':
include/c++/4.7.0/bits/stl_uninitialized.h:77:3: required from 'static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = const S*, _ForwardIterator = S*, …Run Code Online (Sandbox Code Playgroud) 我试图迭代一些std::lists,对它们进行排序.这是天真的方法:
#include<list>
using namespace std;
int main(void){
list<int> a,b,c;
for(auto& l:{a,b,c}) l.sort();
}
Run Code Online (Sandbox Code Playgroud)
生产
aa.cpp:5:25: error: no matching member function for call to 'sort'
for(auto& l:{a,b,c}) l.sort();
~~^~~~
/usr/bin/../lib64/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/stl_list.h:1586:7: note:
candidate function not viable: 'this' argument has type 'const
std::list<int, std::allocator<int> >', but method is not marked const
sort();
^
/usr/bin/../lib64/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/stl_list.h:1596:9: note:
candidate function template not viable: requires 1 argument, but 0 were
provided
sort(_StrictWeakOrdering);
^
1 error generated.
Run Code Online (Sandbox Code Playgroud)
我是否正确地猜测大括号初始化程序正在创建这些列表的副本?有没有办法不复制它们,并使它们在循环中可修改?(除了制作指向它们的指针列表,这是我目前的解决方法).
考虑以下程序:
#include <stdexcept>
#include <stdio.h>
#include <memory>
#include <list>
class Foo {
public:
Foo(){
if (s_ct==0) {throw std::bad_alloc();}
--s_ct;
fprintf(stderr, "ctor %p\n", this);
}
~Foo(){
fprintf(stderr, "dtor %p\n", this);
}
private:
static int s_ct;
};
int Foo::s_ct = 2;
int main(){
try {
std::list<std::shared_ptr<Foo>> l = {
std::make_shared<Foo>(),
std::make_shared<Foo>(),
std::make_shared<Foo>()
};
} catch (std::bad_alloc&) {
fprintf(stderr, "caught exception.\n");
}
fprintf(stderr, "done.\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译如下:
[little:~] $ g++ --version
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.2) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, …Run Code Online (Sandbox Code Playgroud) c++ ×10
initializer-list ×10
c++11 ×6
c++14 ×2
arrays ×1
c++17 ×1
class ×1
constants ×1
constructor ×1
enums ×1
lambda ×1
shared-ptr ×1
template-argument-deduction ×1
templates ×1
vector ×1