我希望使用運算子 [] 中傳遞的運算式。我認為使用可變模板引數可以解決問題,但我錯了……這是在 c 11 中執行此操作的一種方法嗎?
class object {
private:
public:
void values() { std::cout << "finished" << std::endl; }
template <typename T, typename... Type> void values(T arg, Type... args) {
std::cout << arg << " " << std::endl;
values(args...);
}
template<typename... Type> void operator[](Type... args) {
values(args...);
}
};
int main(void) {
object o1 = object();
o1.values(1, 6.2, true, "hello"); // Works fine.
o1[1, 6.2, true]; // Only the last value gets printed eg. true
return 0;
}
更廣泛的目標是,我被要求為此制定一個作業語法
let o3 = object [ values 1, "2", true, -3.14 ];
let o1 = object [ key("x") = -1, key("y") = -2,values 1, "2", true, -3.14 ]; // no commas are missing
在 c 11 中使用 c 11 STL(模板、使用、宏、運算子多載等)。我正在慢慢地想辦法把它拼湊起來
uj5u.com熱心網友回復:
首先,您需要了解operator[]只能取一個引數。您的模板化操作員隱藏了一條非常清楚的錯誤訊息。
struct foo {
void operator[](int,int);
};
結果出錯:
<source>:2:10: error: 'void foo::operator[](int, int)' must have exactly one argument
2 | void operator[](int,int);
| ^~~~~~~~
您可以將其設為可變引數模板,但任何不完全是一個引數的實體化都是不正確的。
弗蘭基,這聽起來像是一個棘手的問題。當您撰寫 C 代碼時,最好使用 C 語法。如果允許使用宏(它們不應該),那么幾乎任何事情都是可能的。您只需要意識到您實際上不再撰寫 C 了。此外,僅僅要求編譯一些語法似乎有點奇怪。我不知道 javascript 并且不確定這兩行應該是什么意思,所以我只這樣做了:讓它以某種方式編譯。
不管怎樣,讓我們??看看能做些什么。
let o3 = object [ values 1, "2", true, -3.14 ];
我想這宣告o3了一個物件,它的初始值設定項是從一個名為的容器中檢索的,該容器object可以通過values 1, "2", true, -3.14. 這條線可以以編譯通過多載一些作出operator,和#define荷蘭國際集團let為auto和values構造,其收集指數(通過它的一個物件operator,):
對于第二行
let o1 = object [ key("x") = -1, key("y") = -2,values 1, "2", true, -3.14 ];
可以玩operator,和濫用類似的伎倆key::operator=。我解釋key為構造一些鍵值對,例如key("x") = -1將值映射-1到字串"x"。它實際上所做的對于接下來的所有臟東西并不是必不可少的。一旦您了解了如何誤用運算子多載,就可以對其進行修改以在細節中執行其他操作。
要查看所有值實際傳遞給的operator[]是從這里偷了一些元組列印功能:https : //stackoverflow.com/a/41171552/4117728
#include <tuple>
#include <string>
#include <typeinfo>
#include <iostream>
#define let auto
//https://stackoverflow.com/a/41171552/4117728
template<class TupType, size_t... I>
void print(const TupType& _tup, std::index_sequence<I...>)
{
std::cout << "(";
(..., (std::cout << (I == 0? "" : ", ") << std::get<I>(_tup)));
std::cout << ")\n";
}
template<class... T>
void print (const std::tuple<T...>& _tup)
{
print(_tup, std::make_index_sequence<sizeof...(T)>());
}
//........................................
struct Object {
template <typename ...T>
struct ObjectIndex {
ObjectIndex() {}
ObjectIndex(std::tuple<T...> ind) : index(ind) {}
std::tuple<T...> index;
template <typename U>
ObjectIndex<T...,U> operator,(const U& u){
return { std::tuple_cat(index,std::make_tuple(u)) };
}
template <typename...U>
ObjectIndex<T...,U...> operator,(const ObjectIndex<U...>& other) {
return { std::tuple_cat(index,other.index) };
}
};
template <typename ...T>
int operator[](ObjectIndex<T...> index){
std::cout << typeid(index.index).name() << "\n";
print(index.index);
return 42;
}
};
struct key {
std::string k;
int val;
key(const std::string& s) : k(s) {}
Object::ObjectIndex<std::string,int> operator=(int v) {
val = v;
return {std::make_tuple(k,val)};
}
};
#define values Object::ObjectIndex<>{} ,
int main() {
Object object;
let o3 = object [ values 1, std::string("2"), true, -3.14 ];
let o1 = object [ key("x") = -1, key("y") = -2,values 1, std::string("2"), true, -3.14 ];
}
現場演示
不要在家里(或其他任何地方)這樣做!
傳遞字串文字存在一些問題,我沒有費心進一步研究,所以我允許自己替換"2"為std::string("2"). 我想通過無盡的錯誤訊息進行更多的戰斗,這也可以解決。
我不知道代碼是否接近這兩行真正應該做的事情。我只是把它當作一個有趣的練習來讓它以某種方式編譯。當operator[]我真正回傳一些東西時,我的想法已經用完了。我很難想象一個具有真正可變引數的容器operator[]。我選擇永遠正確的答案。
TL;DR你能多載operator[]接受多個引數嗎?不可以。您可以多載它以采用封裝任意值的單個引數嗎?當然。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/383311.html
