标签: variant

鸭子打字与旧的"变种"类型和/或界面有何不同?

我一直看到"鸭子打字"这个短语大肆渲染,甚至还遇到了一两个代码示例.我懒得忙着做自己的研究,有人可以简单地告诉我:

  • 'duck type'和old-skool'变体类型'之间的区别,和
  • 提供一个示例,我可能更喜欢鸭子打字而不是变种打字,以及
  • 提供一个我必须使用duck typing来完成的事情的例子?

鸭子打字图由礼貌登记

通过怀疑这种"新"结构的力量,我不是故意要发怒的,而且我不会因为拒绝做研究而避开这个问题,但我正在喋喋不休地谈论我所看到的所有关于这个问题的大肆宣传.最近.它看起来像没有打字(也就是动态打字),所以我没有立即看到优势.

附录:感谢目前为止的例子.在我看来,使用类似'O-> can(Blah)'的东西相当于进行反射查找(可能并不便宜),和/或与编译器可能说的(O是IBlah)大致相同能够检查你,但后者的优点是区分我的IBlah界面和你的IBlah界面,而其他两个没有.当然,对于每种方法都有很多微小的接口会变得混乱,但是那样可以检查很多单独的方法......

...所以我再也没有得到它.在一个全新的麻袋中,它是一个梦幻般的节省时间,还是同样的老东西?需要鸭子打字的例子在哪里?

duck-typing interface variant

43
推荐指数
3
解决办法
3730
查看次数

变量迭代自身 - 不同类型的不同行为

请查看帖子末尾的最新更新.

特别是,请参阅更新4:变体比较诅咒


我已经看到配偶撞到墙上以了解变体是如何工作的,但从来没有想到我会有自己的糟糕时刻.

我已成功使用以下VBA构造:

For i = 1 to i

当这工作完全i是一个整数或者任何数值类型,从1迭代到原始值i.我这样做的地方i是一个ByVal参数 - 你可能会说懒惰 - 让我自己声明一个新的变量.

然后当这个结构"停止"按预期工作时,我遇到了一个错误.经过一些艰难的调试后,我发现当它没有i被声明为显式数字类型时,它的工作方式不同,但是a Variant.问题有两个:

1- ForFor Each循环的确切语义是什么?我的意思是编译器执行的操作顺序是什么,顺序是什么?例如,限制的评估是否在计数器的初始化之前?在循环开始之前,这个限制是否被复制并"修复"了?等等.同样的问题适用于For Each.

2-如何解释变体和显式数字类型的不同结果?有人说变体是一个(不可变的)引用类型,这个定义可以解释观察到的行为吗?

我已经为涉及和语句的不同(独立)场景准备了MCVE,并结合了整数,变体和对象.令人惊讶的结果促使明确定义语义,或者至少检查那些结果是否符合定义的语义.ForFor Each

欢迎所有见解,包括解释一些令人惊讶的结果或其矛盾的部分见解.

谢谢.

Sub testForLoops()
    Dim i As Integer, v As Variant, vv As Variant, obj As Object, rng As Range

    Debug.Print vbCrLf & "Case1 i --> i    ",
    i …
Run Code Online (Sandbox Code Playgroud)

vb6 vba for-loop variant language-lawyer

32
推荐指数
1
解决办法
957
查看次数

如何制作更安全的C++变体访问者,类似于switch语句?

许多人使用C++ 17/boost变体的模式看起来与switch语句非常相似.例如:( 来自cppreference.com的片段)

std::variant<int, long, double, std::string> v = ...;

std::visit(overloaded {
    [](auto arg) { std::cout << arg << ' '; },
    [](double arg) { std::cout << std::fixed << arg << ' '; },
    [](const std::string& arg) { std::cout << std::quoted(arg) << ' '; },
}, v);
Run Code Online (Sandbox Code Playgroud)

问题是当您在访问者中输入错误的类型或更改变体签名时,但忘记更改访问者.您将获得错误的lambda,通常是默认的lambda,而不是获得编译错误,或者您可能会得到一个您没有计划的隐式转换.例如:

v = 2.2;
std::visit(overloaded {
    [](auto arg) { std::cout << arg << ' '; },
    [](float arg) { std::cout << std::fixed << arg << ' '; } // oops, this won't …
Run Code Online (Sandbox Code Playgroud)

c++ visitor variant switch-statement c++17

30
推荐指数
1
解决办法
3676
查看次数

如何返回在VBA中传递给它的(Variant)变量的维数

有谁知道如何返回在VBA中传递给它的(Variant)变量的维数?

excel vba variant dimensions

28
推荐指数
5
解决办法
6万
查看次数

什么是代数数据类型的惯用现代C++?

例如,假设您要在C++中实现电子表格Cell.单元格可以是字符串,数字,也可以是空的.忽略其他情况,例如它是一个公式.

在Haskell中,您可能会执行以下操作:

data Cell = CellStr String | CellDbl Double | None
Run Code Online (Sandbox Code Playgroud)

什么被认为是在C++中实现它的当前"最佳实践"?在带有类型指示符的结构中使用union,还是其他什么?

c++ polymorphism variant algebraic-data-types unions

28
推荐指数
2
解决办法
2956
查看次数

get <string>表示变体在clang ++下失败但不是g ++

以下代码:

variant<string> x = "abc";
cout << get<string>(x) << "\n";
Run Code Online (Sandbox Code Playgroud)

在g ++(版本7.2)下正常工作.但是,当使用libstdc ++在clang ++(版本5.0)下编译时,我在get方法中得到以下错误:

/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/7.2.0/../../../../include/c++/7.2.0/variant:238:46: fatal error: cannot cast 'std::variant<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >' to its private base class 'std::__detail::__variant::_Variant_storage<false, std::
__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >'
      return __get(std::in_place_index<_Np>, std::forward<_Variant>(__v)._M_u);
Run Code Online (Sandbox Code Playgroud)

这是编译器错误,还是我的代码以任何方式违法?

c++ variant clang++ c++17

25
推荐指数
1
解决办法
1806
查看次数

Android Studio:未找到构建变体错误

我是 android 开发的新手,我开始在网上购买的项目上从头开始开发,按照文档,我遇到了一个错误,说没有找到“应用程序”的变体。检查构建文件以确保至少存在一种变体。

这是 build.gradle 代码

apply plugin: 'com.android.application'

android {
compileSdkVersion 29
buildToolsVersion "29.0.1"
defaultConfig {
    applicationId "com.app-10.app"
    minSdkVersion 23
    targetSdkVersion 29
    versionCode 1
    versionName "1.0"
    testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
}
}

dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.vectordrawable:vectordrawable:1.0.1'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
// Third Party Libraries
//Glide library for image fetching from the web
implementation 'com.github.bumptech.glide:glide:4.9.0' …
Run Code Online (Sandbox Code Playgroud)

android build variant android-studio android-gradle-plugin

25
推荐指数
3
解决办法
4万
查看次数

该类型和功能是否已有名称?

在计算机科学中,有两个难题:缓存失效,命名和一个错误。

这是关于第二个问题的:命名事物。

我在寻找这种技术或类型是否已经在其他地方使用并且有名称。 dichotomy是一个不错的名字,但那bools_at_compile_time是一个可怕的名字。

using dichotomy_t = std::variant<std::false_type, std::true_type>;
// (or a struct that inherits from that, and overloads operator bool())

constexpr dichotomy_t dichotomy( bool b ) {
  if (b) return std::true_type{};
  return std::false_type{};
}
template<class F, class...Bools>
constexpr auto bools_at_compile_time( F&& f, Bools...bools ) {
  static_assert( (std::is_same<Bools, bool>{} && ...) );
  return std::visit( std::forward<F>(f), dichotomy(bools)... );
}
Run Code Online (Sandbox Code Playgroud)

dichotomy_t是true和false之间的变体。其运行时表示为01

这可以让您做的是:

auto foo( bool x, bool y ) { // <-- x and …
Run Code Online (Sandbox Code Playgroud)

c++ boolean variant c++17

24
推荐指数
2
解决办法
730
查看次数

无法使用重载的运算符<<()为std :: variant传输std :: endl

这个答案描述了如何流式传输独立的std::variant.但是,它std::variant存储在一个时似乎不起作用std::unordered_map.

以下示例:

#include <iostream>
#include <string>
#include <variant>
#include <complex>
#include <unordered_map>

// https://stackoverflow.com/a/46893057/8414561
template<typename... Ts>
std::ostream& operator<<(std::ostream& os, const std::variant<Ts...>& v)
{
    std::visit([&os](auto&& arg) {
        os << arg;
    }, v);
    return os;
}

int main()
{
    using namespace std::complex_literals;
    std::unordered_map<int, std::variant<int, std::string, double, std::complex<double>>> map{
        {0, 4},
        {1, "hello"},
        {2, 3.14},
        {3, 2. + 3i}
    };

    for (const auto& [key, value] : map)
        std::cout << key << "=" << value …
Run Code Online (Sandbox Code Playgroud)

c++ variant c++17

23
推荐指数
3
解决办法
1082
查看次数

不能在QtCreator中使用g ++ 7.2使用c ++ 17功能

我最近将gcc和g ++更新到版本7.2.我想尝试一下std::experimental::any,std::variant特别是,我在QtCreator中使用Qt 5.9.1.

到目前为止,我已经在项目文件中写了这个:

CONFIG += c++17
Run Code Online (Sandbox Code Playgroud)

我在正确的位置添加了正确的标题:

#include <variant>
#include <experimental/any>
Run Code Online (Sandbox Code Playgroud)

任何工作都很好,没有问题.但是,当我包含变体头文件时,我收到此错误:

/usr/include/c++/7/bits/c++17_warning.h:32: error: #error This file requires compiler and library support for the ISO C++ 2017 standard. This support must be enabled with the -std=c++17 or -std=gnu++17 compiler options.
Run Code Online (Sandbox Code Playgroud)

#error此文件需要编译器和库支持\ ^ ~~~~

我在项目文件中尝试过各种各样的东西,这里是完整列表:

CONFIG += c++17
Run Code Online (Sandbox Code Playgroud)

&

CONFIG += c++1z
Run Code Online (Sandbox Code Playgroud)

&

QMAKE_CXXFLAGS += -std=c++17
Run Code Online (Sandbox Code Playgroud)

&

QMAKE_CXXFLAGS += -std=c++1z
Run Code Online (Sandbox Code Playgroud)

&

CONFIG += c++17
QMAKE_CXXFLAGS += -std=c++17
Run Code Online (Sandbox Code Playgroud)

&

CONFIG += c++1z
QMAKE_CXXFLAGS += -std=c++1z
Run Code Online (Sandbox Code Playgroud)

&

CONFIG …
Run Code Online (Sandbox Code Playgroud)

c++ variant qt-creator c++17

22
推荐指数
2
解决办法
2万
查看次数