C 11 başlatıcı listesi başarısız - ama sadece uzunluğu 2 listelerinde
Aşağı uzunluğu 2 başlatıcı listeleri özel bir durum gibi görünen aslında çok da anlaşılır günlük bir hata buldum! Bu nasıl mümkün olabilir?
Kod Apple LLVM sürüm 5.1 (çınlama-503.0.40), CXXFLAGS=-std=c 11 -stdlib=libc
kullanarak derlendi.
#include <stdio.h>
#include <string>
#include <vector>
using namespace std;
typedef vector<string> Strings;
void print(string const& s) {
printf(s.c_str());
printf("\n");
}
void print(Strings const& ss, string const& name) {
print("Test " name);
print("Number of strings: " to_string(ss.size()));
for (auto& s: ss) {
auto t = "length = " to_string(s.size()) ": " s;
print(t);
}
print("\n");
}
void test() {
Strings a{{"hello"}}; print(a, "a");
Strings b{{"hello", "there"}}; print(b, "b");
Strings c{{"hello", "there", "kids"}}; print(c, "c");
Strings A{"hello"}; print(A, "A");
Strings B{"hello", "there"}; print(B, "B");
Strings C{"hello", "there", "kids"}; print(C, "C");
}
int main() {
test();
}
Çıkış:
Test a
Number of strings: 1
length = 5: hello
Test b
Number of strings: 1
length = 8: hello
Test c
Number of strings: 3
length = 5: hello
length = 5: there
length = 4: kids
Test A
Number of strings: 1
length = 5: hello
Test B
Number of strings: 2
length = 5: hello
length = 5: there
Test C
Number of strings: 3
length = 5: hello
length = 5: there
length = 4: kids
Dostum, ben de eklemek boyu sahte dize test b gibi görünüyor belirsiz - her zaman büyüktür ilk başlatıcı dize ama değişik bir fazla uzunluğu ilk dize için toplam uzunlukları iki dizeleri başlatıcı.
CEVAP
Giriş
Aşağıdaki bildiriyi hayal ve kullanımı:
struct A {
A (std::initializer_list<std::string>);
};
A {{"a" }}; // (A), initialization of 1 string
A {{"a", "b" }}; // (B), initialization of 1 string << !!
A {{"a", "b", "c"}}; // (C), initialization of 3 strings
(BirveCherc-stil dizebir (1) başlatma neden oluyor::standart bir dizeeğer söz konusu sizin de ifade ettiğiniz gibi , ama,, (B) farklıdır.
Derleyici olası bir yapı olduğunu görür::standart bir dizebir kullanarakbaşlarveson yineleyicive ayrıştırma ifade edildiği gibiBböyle tek tek başlatıcılar olarak "a"
"b"
kullanarak üzerinde inşa tercihikielemanları.
A { std::string { "a", "b" } }; // the compiler's interpretation of (B)
< / ^ br .
Not: Türünün
"a"
"b"
char const[2]
yazın ya da dolaylı olarak çürüme içinechar const*
bir işaretçi tipi hangisi uygun hareket etmek gibi bir yineleyici gösteren yabaşlaryasonunda*22..*amadikkatli olmalıyız: sebep oluyortanımsız davranışyok (garantili) beri çağırma üzerine iki işaretçiler arasındaki ilişki yapıcı söyledi.
Açıklama
Ne zaman yapıcı bir almaya çağırır::initializer_list stdçift parantez {{ a, b, ... }}
iki olası yorumlar vardır kullanma
Dış parantez kurucu kendisi bakın, iç parantez unsurları katılmak gösterir::initializer_list stdya da:
Dış diş telleri bakın::initializer_list stdiçindeki bir elemanın başlatma gösterir iç parantez oysa.
Tercih yapmak için2)mümkün olduğunda, ve std::string
bir kurucu iki yineleyicisi alarak bu yana, std::vector<std::string> {{ "hello", "there" }}
varsa denmesinden.
Daha fazla örnek:
std::vector<std::string> {{"this", "is"}, {"stackoverflow"}}.size (); // yields 2
Çözüm
Bu tür başlatmak için çift parantez kullanmayın.
S3 politikası sınırlayıcı erişim sadec...
Scala: [List] Geleceği hiçe sayılarak ...
OS X 10.6.6 ve "adb devices"...
Nasıl sadece yerel şubelerinin listesi...
Python: bir dosyaya Yazma listesi...