有没有办法在C ++中创建类型变量?

时间:2019-10-12 08:35:57

标签: c++ templates c++17

我对使类型可变的方法感到好奇。 下面的代码解释了我的意思:

function Keep_Logs_And_Move_Files([int]$No_files_to_keep)
    {
        Write-Host "Count of keep files: " $No_files_to_keep
        # Check and create Archive dir if not exist

        Write-Host "Count of keep files: " $No_files_to_keep
        # Check and create Archive dir if not exist
        $source_dir="D:\Log_Test_Direcotories\Log2"
        $archiv_dir="D:\Log_Test_Direcotories\Log2_archiv"
        $count_of_Files= Get-ChildItem $source_dir | Measure-Object | Select-Object Count
        $existing_files= ls $source_dir

        IF ($count_of_Files.Count -gt $No_files_to_keep){

            # Get the number of latest files
            $files_to_keep=Get-ChildItem -Path $source_dir | Where-Object { -not $_.PsIsContainer } | Sort-Object LastWriteTime -Descending | Select-Object -first $No_files_to_keep

            #compare exsting all files with files_to_keep to get  excluded_files that need to be moved out
            $exclude_files=Compare-Object -ReferenceObject ($files_to_keep | Sort-Object ) -DifferenceObject ($existing_files | Sort-Object)

            #Filter for oly files not directory
            #$Filtered_files=gci -af $exclude_files

            #Write-Host "Filtered files $Filtered_files"

            #Move exclude_files to archive
            foreach($i in $exclude_files){
                Write-Host "Moving file $i..." 
                $i.InputObject | Move-Item -Destination $archiv_dir
            }

        } else{
            Write-Host "OK! Existing files are equal/lesser to the number required latest files!"

        }
    }

#Calling function
Keep_Logs_And_Move_Files 3

当然,据我所知,此代码将永远无法工作,因为using var = type_var<int>; // currently var is of type type_var<int> /// somewhere like in constexpr functions var::store<float>; // now var is of type type_var<float> static_assert(std::is_same<var::get_type, float>::value, ""); 将使using成为“不可变的”。

但是,我仍然想知道是否有一种方法来可变地存储类型。

1 个答案:

答案 0 :(得分:0)

  

我要问的问题是,有没有一种方法可以使存储“类型”的元素存储在该类型中,而该类型可以在编译时更改。

简单的答案是不!

C ++编程语言没有诸如“编译时间变量”之类的东西。所有一切都遵循One Definition Rule (ODR)

C ++通过templates提供一种自己的编译时语言,通常称为Template MetaProgramming (TMP)。TMP语言使用functional programming language的一般概念。

来自以上链接的文本:

  

功能程序没有赋值语句,也就是说,功能程序中的变量值一旦定义就永远不会改变。

如果我了解您的伪示例代码,则您会想到以下内容:

template < auto x >
struct Variable
{
    static constexpr decltype(x) value = x;
};

Variable< 10 > intvar;
Variable< 'a' > charvar;

int main()
{
    // accessing the data:
    std::cout << intvar.value << std::endl;
    std::cout << charvar.value << std::endl;
}

但是在模板和类型的世界中,仅通过没有任何类型的语法就无法再为模板分配新值或类型。

您也可以在TMP中编程算法,但是“调用”的所有“结果”都不是任何类型的变量,它们总是定义新的“值”。

一些模板元编程的例子。该示例显示了如何编写 “添加”“功能”。它将添加两个类型的容器...

// define a data structure which can contain a list of types
template < typename ... TYPES >
struct TypeContainer;

// let us define some TMP "variables", which are types in c++ 
using list1 = TypeContainer<int, float, int >;
using list2 = TypeContainer< char, bool, int >;

// and now we define a TMP "function"
template < typename ... PARMS > struct Concat;

// which simply adds two typelists
template < typename ... LIST1, typename ... LIST2 >
struct Concat< TypeContainer< LIST1... >, TypeContainer< LIST2...>>
{
    using RESULT = TypeContainer< LIST1..., LIST2...>;
};

using list3 = Concat<list1, list2 >::RESULT;

// But you never can change the "variable", because of the 
// One Definition Rule (ODR)
// ( will fail to compile )
//using list2 = Concat<list1, list2 >::RESULT;

// helper to let us know what we have in the typelists:
// works for gcc or clang but is implementation specific
template < typename T>
void Print()
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}

int main()
{
    Print<list3>();
}

您会发现STL中已经定义了这样的算法。在那里,您将std::tuple作为类型容器,并将std::tuple_cat作为两个元组的“加”。我的代码仅应为您提供一个简单的示例,以了解我们在做什么,而无需在STL内部做一些不可思议的事情。